OpenJDK / jdk / jdk
changeset 6523:d1c0054bff1c
Merge
author | lana |
---|---|
date | Thu, 02 Sep 2010 22:11:05 -0700 |
parents | 3b995fa42e90 adf468d05745 |
children | b6e3ce78bea6 |
files | jdk/src/share/classes/sun/java2d/pisces/PiscesMath.java jdk/src/share/classes/sun/java2d/pisces/Transform4.java |
diffstat | 248 files changed, 15555 insertions(+), 2323 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Wed Sep 01 17:37:45 2010 -0700 +++ b/.hgtags Thu Sep 02 22:11:05 2010 -0700 @@ -79,3 +79,6 @@ 88db80c8e49cea352c2900f689600dc410761c1f jdk7-b102 64770970865839b0443066370e7d476ef47e90cd jdk7-b103 10bc903a228d3a8efdf46fb8c3fcf82a59b88bc5 jdk7-b104 +1ce7938efb03224ccc8b3cdd7803eb39e889539c jdk7-b105 +6bdae472f77205046703b685eff2ac4f7a0ecf4e jdk7-b106 +439de530aac531a360beedba6e2fe51e17292cc0 jdk7-b107
--- a/.hgtags-top-repo Wed Sep 01 17:37:45 2010 -0700 +++ b/.hgtags-top-repo Thu Sep 02 22:11:05 2010 -0700 @@ -79,3 +79,6 @@ a136a51f5113da4dad3853b74a8536ab583ab112 jdk7-b102 be2aedc4e3b1751c1310f334242ba69e90867f38 jdk7-b103 f8be576feefce0c6695f188ef97ec16b73ad9cfd jdk7-b104 +9f96a4269d7727dad68864eaab795eafce270311 jdk7-b105 +43096cccf1cee749c2f4e7714ee71f4e9e0f4d7f jdk7-b106 +7d396ad455c3b2f68b0d7094891c5aba7c757a6e jdk7-b107
--- a/corba/.hgtags Wed Sep 01 17:37:45 2010 -0700 +++ b/corba/.hgtags Thu Sep 02 22:11:05 2010 -0700 @@ -79,3 +79,6 @@ 78561a95779090b5106c8d0f1a75360a027ef087 jdk7-b102 11e7678c3eb169b77d9a9892fe5e3dfa1d1a0d51 jdk7-b103 9607213481d400ac477183191cc080e1bef6f475 jdk7-b104 +6f21b030092fb61244cc8a0aedf8058f7c022b81 jdk7-b105 +519daea48888196af76a975a3b31258efa860bad jdk7-b106 +232adb83eae8375439ccff65b6e205ca0da0510d jdk7-b107
--- a/hotspot/.hgtags Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/.hgtags Thu Sep 02 22:11:05 2010 -0700 @@ -110,3 +110,8 @@ cb4250ef73b21de6c487ea14e2b0b99eed67b4b6 jdk7-b103 e55900b5c1b865cac17e18abc639c7dc50de7fd8 hs19-b04 b4acf10eb134fe930802c97e36db65e7ccb544b5 jdk7-b104 +6709c14587c2cc6faca208767335afeb01e33de5 jdk7-b105 +1b81ca701fa5fc30adc4cfdaa4bdd153df5e6c86 jdk7-b106 +cc3fdfeb54b049f18edcf3463e6ab051d0b7b609 hs19-b05 +688a538aa65412178286ae2a6b0c00b6711e121b hs19-b06 +bf496cbe9b74dda5975a1559da7ecfdd313e509e jdk7-b107
--- a/hotspot/agent/src/os/linux/ps_proc.c Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/agent/src/os/linux/ps_proc.c Thu Sep 02 22:11:05 2010 -0700 @@ -253,7 +253,11 @@ if (nwords > 5 && find_lib(ph, word[5]) == false) { intptr_t base; lib_info* lib; +#ifdef _LP64 sscanf(word[0], "%lx", &base); +#else + sscanf(word[0], "%x", &base); +#endif if ((lib = add_lib_info(ph, word[5], (uintptr_t)base)) == NULL) continue; // ignore, add_lib_info prints error
--- a/hotspot/make/Makefile Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/Makefile Thu Sep 02 22:11:05 2010 -0700 @@ -85,14 +85,21 @@ C2_VM_TARGETS=product fastdebug optimized jvmg KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero +SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark # JDK directory list JDK_DIRS=bin include jre lib demo all: all_product all_fastdebug +ifndef BUILD_CLIENT_ONLY all_product: product product1 productkernel docs export_product all_fastdebug: fastdebug fastdebug1 fastdebugkernel docs export_fastdebug all_debug: jvmg jvmg1 jvmgkernel docs export_debug +else +all_product: product1 docs export_product +all_fastdebug: fastdebug1 docs export_fastdebug +all_debug: jvmg1 docs export_debug +endif all_optimized: optimized optimized1 optimizedkernel docs export_optimized allzero: all_productzero all_fastdebugzero @@ -101,6 +108,12 @@ all_debugzero: jvmgzero docs export_debug all_optimizedzero: optimizedzero docs export_optimized +allshark: all_productshark all_fastdebugshark +all_productshark: productshark docs export_product +all_fastdebugshark: fastdebugshark docs export_fastdebug +all_debugshark: jvmgshark docs export_debug +all_optimizedshark: optimizedshark docs export_optimized + # Do everything world: all create_jdk @@ -131,6 +144,10 @@ $(CD) $(GAMMADIR)/make; \ $(MAKE) VM_TARGET=$@ generic_buildzero $(ALT_OUT) +$(SHARK_VM_TARGETS): + $(CD) $(GAMMADIR)/make; \ + $(MAKE) VM_TARGET=$@ generic_buildshark $(ALT_OUT) + # Build compiler1 (client) rule, different for platforms generic_build1: $(MKDIR) -p $(OUTPUTDIR) @@ -197,6 +214,12 @@ $(MAKE) -f $(ABS_OS_MAKEFILE) \ $(MAKE_ARGS) $(VM_TARGET) +generic_buildshark: + $(MKDIR) -p $(OUTPUTDIR) + $(CD) $(OUTPUTDIR); \ + $(MAKE) -f $(ABS_OS_MAKEFILE) \ + $(MAKE_ARGS) $(VM_TARGET) + # Export file rule generic_export: $(EXPORT_LIST) export_product: @@ -228,15 +251,22 @@ C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2 KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero +SHARK_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_shark C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR) C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR) KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR) ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR) +SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR) # Misc files and generated files need to come from C1 or C2 area ifeq ($(ZERO_BUILD), true) +ifeq ($(SHARK_BUILD), true) + MISC_DIR=$(SHARK_DIR) + GEN_DIR=$(SHARK_BASE_DIR)/generated +else MISC_DIR=$(ZERO_DIR) GEN_DIR=$(ZERO_BASE_DIR)/generated +endif else ifeq ($(ARCH_DATA_MODEL), 32) MISC_DIR=$(C1_DIR) @@ -290,11 +320,20 @@ # Shared Library ifneq ($(OSNAME),windows) ifeq ($(ZERO_BUILD), true) + ifeq ($(SHARK_BUILD), true) +$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(SHARK_DIR)/%.so + $(install-file) +$(EXPORT_SERVER_DIR)/%.so: $(SHARK_DIR)/%.so + $(install-file) + else $(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(ZERO_DIR)/%.so $(install-file) $(EXPORT_SERVER_DIR)/%.so: $(ZERO_DIR)/%.so $(install-file) + endif else +$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C1_DIR)/%.so + $(install-file) $(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C2_DIR)/%.so $(install-file) $(EXPORT_CLIENT_DIR)/%.so: $(C1_DIR)/%.so @@ -348,6 +387,7 @@ $(RM) -r $(C2_DIR) $(RM) -r $(KERNEL_DIR) $(RM) -r $(ZERO_DIR) + $(RM) -r $(SHARK_DIR) clean_export: $(RM) -r $(EXPORT_PATH) clean_jdk:
--- a/hotspot/make/defs.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/defs.make Thu Sep 02 22:11:05 2010 -0700 @@ -192,13 +192,16 @@ # Use uname output for SRCARCH, but deal with platform differences. If ARCH # is not explicitly listed below, it is treated as x86. - SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 zero,$(ARCH))) + SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc zero,$(ARCH))) ARCH/ = x86 ARCH/sparc = sparc ARCH/sparc64= sparc ARCH/ia64 = ia64 ARCH/amd64 = x86 ARCH/x86_64 = x86 + ARCH/ppc64 = ppc + ARCH/ppc = ppc + ARCH/arm = arm ARCH/zero = zero # BUILDARCH is usually the same as SRCARCH, except for sparcv9 @@ -223,6 +226,9 @@ LIBARCH/sparc = sparc LIBARCH/sparcv9 = sparcv9 LIBARCH/ia64 = ia64 + LIBARCH/ppc64 = ppc + LIBARCH/ppc = ppc + LIBARCH/arm = arm LIBARCH/zero = $(ZERO_LIBARCH) LP64_ARCH = sparcv9 amd64 ia64 zero
--- a/hotspot/make/hotspot_version Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/hotspot_version Thu Sep 02 22:11:05 2010 -0700 @@ -35,7 +35,7 @@ HS_MAJOR_VER=19 HS_MINOR_VER=0 -HS_BUILD_NUMBER=05 +HS_BUILD_NUMBER=06 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/hotspot/make/linux/Makefile Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/Makefile Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -168,6 +168,13 @@ # profiledzero zero <os>_<arch>_zero/profiled # productzero zero <os>_<arch>_zero/product # +# debugshark shark <os>_<arch>_shark/debug +# fastdebugshark shark <os>_<arch>_shark/fastdebug +# jvmgshark shark <os>_<arch>_shark/jvmg +# optimizedshark shark <os>_<arch>_shark/optimized +# profiledshark shark <os>_<arch>_shark/profiled +# productshark shark <os>_<arch>_shark/product +# # What you get with each target: # # debug* - "thin" libjvm_g - debug info linked into the gamma_g launcher @@ -191,12 +198,14 @@ SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS)) SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS)) SUBDIRS_ZERO = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS)) +SUBDIRS_SHARK = $(addprefix $(OSNAME)_$(VARIANTARCH)_shark/,$(TARGETS)) TARGETS_C2 = $(TARGETS) TARGETS_C1 = $(addsuffix 1,$(TARGETS)) TARGETS_TIERED = $(addsuffix tiered,$(TARGETS)) TARGETS_CORE = $(addsuffix core,$(TARGETS)) TARGETS_ZERO = $(addsuffix zero,$(TARGETS)) +TARGETS_SHARK = $(addsuffix shark,$(TARGETS)) BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) @@ -213,6 +222,7 @@ @echo " $(TARGETS_C1)" @echo " $(TARGETS_CORE)" @echo " $(TARGETS_ZERO)" + @echo " $(TARGETS_SHARK)" checks: check_os_version check_j2se_version @@ -266,6 +276,10 @@ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH) +$(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero + $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks + $(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH) + platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in $(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@ @@ -306,11 +320,19 @@ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install endif +$(TARGETS_SHARK): $(SUBDIRS_SHARK) + cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) + cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma +ifdef INSTALL + cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install +endif + # Just build the tree, and nothing else: tree: $(SUBDIRS_C2) tree1: $(SUBDIRS_C1) treecore: $(SUBDIRS_CORE) treezero: $(SUBDIRS_ZERO) +treeshark: $(SUBDIRS_SHARK) # Doc target. This is the same for all build options. # Hence create a docs directory beside ...$(ARCH)_[...] @@ -327,20 +349,22 @@ zero: jvmgzero productzero +shark: jvmgshark productshark + clean_docs: rm -rf $(SUBDIR_DOCS) -clean_compiler1 clean_compiler2 clean_core clean_zero: +clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark: rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@) -clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_docs +clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_shark clean_docs include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make #------------------------------------------------------------------------------- -.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) -.PHONY: tree tree1 treecore treezero -.PHONY: all compiler1 compiler2 core zero -.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero docs clean_docs +.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK) +.PHONY: tree tree1 treecore treezero treeshark +.PHONY: all compiler1 compiler2 core zero shark +.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs .PHONY: checks check_os_version check_j2se_version
--- a/hotspot/make/linux/makefiles/build_vm_def.sh Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/build_vm_def.sh Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,12 @@ #!/bin/sh -nm --defined-only $* | awk ' +# If we're cross compiling use that path for nm +if [ "$ALT_COMPILER_PATH" != "" ]; then +NM=$ALT_COMPILER_PATH/nm +else +NM=nm +fi + +$NM --defined-only $* | awk ' { if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";" } '
--- a/hotspot/make/linux/makefiles/buildtree.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/buildtree.make Thu Sep 02 22:11:05 2010 -0700 @@ -339,12 +339,16 @@ WRONG_DATA_MODE_MSG = \ echo "JAVA_HOME must point to $(DATA_MODE)bit JDK." +CROSS_COMPILING_MSG = \ + echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run." + test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java @echo Creating $@ ... $(QUIETLY) ( \ echo '#!/bin/sh'; \ $(BUILDTREE_COMMENT); \ echo '. ./env.sh'; \ + echo "if [ \"$(CROSS_COMPILE_ARCH)\" != \"\" ]; then { $(CROSS_COMPILING_MSG); exit 0; }; fi"; \ echo "if [ -z \$$JAVA_HOME ]; then { $(NO_JAVA_HOME_MSG); exit 0; }; fi"; \ echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>&1 > /dev/null"; \ echo "then"; \
--- a/hotspot/make/linux/makefiles/defs.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/defs.make Thu Sep 02 22:11:05 2010 -0700 @@ -98,6 +98,22 @@ HS_ARCH = x86 endif +# ARM +ifeq ($(ARCH), arm) + ARCH_DATA_MODEL = 32 + PLATFORM = linux-arm + VM_PLATFORM = linux_arm + HS_ARCH = arm +endif + +# PPC +ifeq ($(ARCH), ppc) + ARCH_DATA_MODEL = 32 + PLATFORM = linux-ppc + VM_PLATFORM = linux_ppc + HS_ARCH = ppc +endif + JDK_INCLUDE_SUBDIR=linux # FIXUP: The subdirectory for a debug build is NOT the same on all platforms @@ -107,22 +123,32 @@ # client and server subdirectories have symbolic links to ../libjsig.so EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so +EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server -EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server +ifndef BUILD_CLIENT_ONLY EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so +endif + ifneq ($(ZERO_BUILD), true) ifeq ($(ARCH_DATA_MODEL), 32) EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so - EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar - else - ifeq ($(ARCH),ia64) - else - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so - EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar - endif endif endif + +# Serviceability Binaries +# No SA Support for PPC, IA64, ARM or zero +ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so \ + $(EXPORT_LIB_DIR)/sa-jdi.jar +ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so \ + $(EXPORT_LIB_DIR)/sa-jdi.jar +ADD_SA_BINARIES/ppc = +ADD_SA_BINARIES/ia64 = +ADD_SA_BINARIES/arm = +ADD_SA_BINARIES/zero = + +EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH)) + +
--- a/hotspot/make/linux/makefiles/gcc.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/gcc.make Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,14 @@ #------------------------------------------------------------------------ # CC, CPP & AS +ifdef ALT_COMPILER_PATH +CPP = $(ALT_COMPILER_PATH)/g++ +CC = $(ALT_COMPILER_PATH)/gcc +else CPP = g++ CC = gcc +endif + AS = $(CC) -c # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only @@ -55,6 +61,9 @@ ifeq ($(ZERO_BUILD), true) CFLAGS += $(LIBFFI_CFLAGS) endif +ifeq ($(SHARK_BUILD), true) +CFLAGS += $(LLVM_CFLAGS) +endif CFLAGS += $(VM_PICFLAG) CFLAGS += -fno-rtti CFLAGS += -fno-exceptions @@ -67,18 +76,31 @@ ARCHFLAG/ia64 = ARCHFLAG/sparc = -m32 -mcpu=v9 ARCHFLAG/sparcv9 = -m64 -mcpu=v9 +ARCHFLAG/arm = -fsigned-char ARCHFLAG/zero = $(ZERO_ARCHFLAG) +ifndef E500V2 +ARCHFLAG/ppc = -mcpu=powerpc +endif CFLAGS += $(ARCHFLAG) AOUT_FLAGS += $(ARCHFLAG) LFLAGS += $(ARCHFLAG) ASFLAGS += $(ARCHFLAG) +ifdef E500V2 +CFLAGS += -DE500V2 +endif + # Use C++ Interpreter ifdef CC_INTERP CFLAGS += -DCC_INTERP endif +# Build for embedded targets +ifdef JAVASE_EMBEDDED + CFLAGS += -DJAVASE_EMBEDDED +endif + # Keep temporary files (.ii, .s) ifdef NEED_ASM CFLAGS += -save-temps @@ -171,6 +193,8 @@ # Note: The Itanium gcc compiler crashes when using -gstabs. DEBUG_CFLAGS/ia64 = -g DEBUG_CFLAGS/amd64 = -g +DEBUG_CFLAGS/arm = -g +DEBUG_CFLAGS/ppc = -g DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH)) ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) DEBUG_CFLAGS += -gstabs @@ -181,3 +205,15 @@ DEBUG_CFLAGS = -g CFLAGS += $(DEBUG_CFLAGS) endif + +# If we are building HEADLESS, pass on to VM +# so it can set the java.awt.headless property +ifdef HEADLESS +CFLAGS += -DHEADLESS +endif + +# We are building Embedded for a small device +# favor code space over speed +ifdef MINIMIZE_RAM_USAGE +CFLAGS += -DMINIMIZE_RAM_USAGE +endif
--- a/hotspot/make/linux/makefiles/product.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/product.make Thu Sep 02 22:11:05 2010 -0700 @@ -46,7 +46,11 @@ # use -g to strip library as -x will discard its symbol table; -x is fine for # executables. -STRIP = strip +ifdef CROSS_COMPILE_ARCH + STRIP = $(ALT_COMPILER_PATH)/strip +else + STRIP = strip +endif STRIP_LIBJVM = $(STRIP) -g $@ || exit 1; STRIP_AOUT = $(STRIP) -x $@ || exit 1;
--- a/hotspot/make/linux/makefiles/sa.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/sa.make Thu Sep 02 22:11:05 2010 -0700 @@ -55,10 +55,13 @@ SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties # if $(AGENT_DIR) does not exist, we don't build SA -# also, we don't build SA on Itanium or zero. +# also, we don't build SA on Itanium, PowerPC, ARM or zero. all: - if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \ + if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" \ + -a "$(SRCARCH)" != "arm" \ + -a "$(SRCARCH)" != "ppc" \ + -a "$(SRCARCH)" != "zero" ] ; then \ $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \ fi
--- a/hotspot/make/linux/makefiles/saproc.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/saproc.make Thu Sep 02 22:11:05 2010 -0700 @@ -53,10 +53,10 @@ endif # if $(AGENT_DIR) does not exist, we don't build SA -# also, we don't build SA on Itanium or zero. +# also, we don't build SA on Itanium, PPC, ARM or zero. checkAndBuildSA: - $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \ + $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "arm" -a "$(SRCARCH)" != "ppc" -a "$(SRCARCH)" != "zero" ] ; then \ $(MAKE) -f vm.make $(LIBSAPROC); \ fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/make/linux/makefiles/shark.make Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,32 @@ +# +# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright 2008, 2010 Red Hat, Inc. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +# Sets make macros for making Shark version of VM + +TYPE = SHARK + +VM_SUBDIR = server + +CFLAGS += -DSHARK
--- a/hotspot/make/linux/makefiles/top.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/top.make Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,7 @@ Include_DBs/COMPILER2 = $(Include_DBs/CORE) $(VM)/includeDB_compiler2 Include_DBs/TIERED = $(Include_DBs/CORE) $(VM)/includeDB_compiler1 $(VM)/includeDB_compiler2 Include_DBs/ZERO = $(Include_DBs/CORE) $(VM)/includeDB_zero +Include_DBs/SHARK = $(Include_DBs/ZERO) $(VM)/includeDB_shark Include_DBs = $(Include_DBs/$(TYPE)) Cached_plat = $(GENERATED)/platform.current
--- a/hotspot/make/linux/makefiles/vm.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/linux/makefiles/vm.make Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -98,6 +98,7 @@ # Extra flags from gnumake's invocation or environment CFLAGS += $(EXTRA_CFLAGS) +LFLAGS += $(EXTRA_CFLAGS) LIBS += -lm -ldl -lpthread @@ -136,10 +137,14 @@ vm.def: $(Res_Files) $(Obj_Files) sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@ -ifeq ($(ZERO_LIBARCH), ppc64) +ifeq ($(SHARK_BUILD), true) STATIC_CXX = false else - STATIC_CXX = true + ifeq ($(ZERO_LIBARCH), ppc64) + STATIC_CXX = false + else + STATIC_CXX = true + endif endif ifeq ($(LINK_INTO),AOUT) @@ -167,6 +172,10 @@ ifeq ($(ZERO_BUILD), true) LIBS_VM += $(LIBFFI_LIBS) endif +ifeq ($(SHARK_BUILD), true) + LFLAGS_VM += $(LLVM_LDFLAGS) + LIBS_VM += $(LLVM_LIBS) +endif LINK_VM = $(LINK_LIB.c) @@ -210,15 +219,17 @@ $(LINK_LIB.CC/POST_HOOK) \ 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 \ - /usr/sbin/selinuxenabled; \ - if [ $$? = 0 ] ; then \ - /usr/bin/chcon -t textrel_shlib_t $@; \ - if [ $$? != 0 ]; then \ - echo "ERROR: Cannot chcon $@"; \ - fi \ - fi \ - fi \ + if [ \"$(CROSS_COMPILE_ARCH)\" = \"\" ] ; then \ + if [ -x /usr/sbin/selinuxenabled ] ; then \ + /usr/sbin/selinuxenabled; \ + if [ $$? = 0 ] ; then \ + /usr/bin/chcon -t textrel_shlib_t $@; \ + if [ $$? != 0 ]; then \ + echo "ERROR: Cannot chcon $@"; \ + fi \ + fi \ + fi \ + fi \ } DEST_JVM = $(JDK_LIBDIR)/$(VM_SUBDIR)/$(LIBJVM)
--- a/hotspot/make/solaris/makefiles/defs.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/solaris/makefiles/defs.make Thu Sep 02 22:11:05 2010 -0700 @@ -70,20 +70,24 @@ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server +ifneq ($(BUILD_CLIENT_ONLY),true) EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so +endif ifeq ($(ARCH_DATA_MODEL), 32) EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so - EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.so + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.so - EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.so EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.so + ifneq ($(BUILD_CLIENT_ONLY), true) + EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.so + EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.so + endif endif EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
--- a/hotspot/make/solaris/makefiles/sparcWorks.make Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/make/solaris/makefiles/sparcWorks.make Thu Sep 02 22:11:05 2010 -0700 @@ -145,11 +145,20 @@ OPT_CFLAGS/O2=-xO2 OPT_CFLAGS/NOOPT=-xO1 +################################################# +# Begin current (>=5.9) Forte compiler options # +################################################# + ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1) ifeq ($(Platform_arch), x86) OPT_CFLAGS/NO_TAIL_CALL_OPT = -Wu,-O~yz OPT_CCFLAGS/NO_TAIL_CALL_OPT = -Qoption ube -O~yz +OPT_CFLAGS/stubGenerator_x86_32.o = $(OPT_CFLAGS) -xspace +OPT_CFLAGS/stubGenerator_x86_64.o = $(OPT_CFLAGS) -xspace endif # Platform_arch == x86 +ifeq ("${Platform_arch}", "sparc") +OPT_CFLAGS/stubGenerator_sparc.o = $(OPT_CFLAGS) -xspace +endif endif # COMPILER_REV_NUMERIC >= 509 #################################################
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -626,7 +626,7 @@ } // This code sequence is relocatable to any address, even on LP64. -void MacroAssembler::jumpl(AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line) { +void MacroAssembler::jumpl(const AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line) { assert_not_delayed(); // Force fixed length sethi because NativeJump and NativeFarCall don't handle // variable length instruction streams. @@ -672,7 +672,7 @@ } } -void MacroAssembler::jump(AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) { +void MacroAssembler::jump(const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) { jumpl(addrlit, temp, G0, offset, file, line); }
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -1974,12 +1974,12 @@ // address pseudos: make these names unlike instruction names to avoid confusion inline intptr_t load_pc_address( Register reg, int bytes_to_skip ); - inline void load_contents(AddressLiteral& addrlit, Register d, int offset = 0); - inline void load_ptr_contents(AddressLiteral& addrlit, Register d, int offset = 0); - inline void store_contents(Register s, AddressLiteral& addrlit, Register temp, int offset = 0); - inline void store_ptr_contents(Register s, AddressLiteral& addrlit, Register temp, int offset = 0); - inline void jumpl_to(AddressLiteral& addrlit, Register temp, Register d, int offset = 0); - inline void jump_to(AddressLiteral& addrlit, Register temp, int offset = 0); + inline void load_contents(const AddressLiteral& addrlit, Register d, int offset = 0); + inline void load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset = 0); + inline void store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0); + inline void store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0); + inline void jumpl_to(const AddressLiteral& addrlit, Register temp, Register d, int offset = 0); + inline void jump_to(const AddressLiteral& addrlit, Register temp, int offset = 0); inline void jump_indirect_to(Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0); // ring buffer traceable jumps @@ -1987,8 +1987,8 @@ void jmp2( Register r1, Register r2, const char* file, int line ); void jmp ( Register r1, int offset, const char* file, int line ); - void jumpl(AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line); - void jump (AddressLiteral& addrlit, Register temp, int offset, const char* file, int line); + void jumpl(const AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line); + void jump (const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line); // argument pseudos:
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -650,28 +650,28 @@ } -inline void MacroAssembler::load_contents(AddressLiteral& addrlit, Register d, int offset) { +inline void MacroAssembler::load_contents(const AddressLiteral& addrlit, Register d, int offset) { assert_not_delayed(); sethi(addrlit, d); ld(d, addrlit.low10() + offset, d); } -inline void MacroAssembler::load_ptr_contents(AddressLiteral& addrlit, Register d, int offset) { +inline void MacroAssembler::load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset) { assert_not_delayed(); sethi(addrlit, d); ld_ptr(d, addrlit.low10() + offset, d); } -inline void MacroAssembler::store_contents(Register s, AddressLiteral& addrlit, Register temp, int offset) { +inline void MacroAssembler::store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) { assert_not_delayed(); sethi(addrlit, temp); st(s, temp, addrlit.low10() + offset); } -inline void MacroAssembler::store_ptr_contents(Register s, AddressLiteral& addrlit, Register temp, int offset) { +inline void MacroAssembler::store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) { assert_not_delayed(); sethi(addrlit, temp); st_ptr(s, temp, addrlit.low10() + offset); @@ -679,7 +679,7 @@ // This code sequence is relocatable to any address, even on LP64. -inline void MacroAssembler::jumpl_to(AddressLiteral& addrlit, Register temp, Register d, int offset) { +inline void MacroAssembler::jumpl_to(const AddressLiteral& addrlit, Register temp, Register d, int offset) { assert_not_delayed(); // Force fixed length sethi because NativeJump and NativeFarCall don't handle // variable length instruction streams. @@ -688,7 +688,7 @@ } -inline void MacroAssembler::jump_to(AddressLiteral& addrlit, Register temp, int offset) { +inline void MacroAssembler::jump_to(const AddressLiteral& addrlit, Register temp, int offset) { jumpl_to(addrlit, temp, G0, offset); }
--- a/hotspot/src/cpu/sparc/vm/bytecodeInterpreter_sparc.inline.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/bytecodeInterpreter_sparc.inline.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -236,19 +236,19 @@ } inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) { - return op1 << op2; + return op1 << (op2 & 0x1f); } inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) { - return op1 >> op2; // QQ op2 & 0x1f?? + return op1 >> (op2 & 0x1f); } inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) { return op1 - op2; } -inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { - return ((juint) op1) >> op2; // QQ op2 & 0x1f?? +inline juint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { + return ((juint) op1) >> (op2 & 0x1f); } inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -409,7 +409,7 @@ LIR_Opr lock = FrameMap::G1_opr; LIR_Opr hdr = FrameMap::G3_opr; LIR_Opr obj_temp = FrameMap::G4_opr; - monitor_exit(obj_temp, lock, hdr, x->monitor_no()); + monitor_exit(obj_temp, lock, hdr, LIR_OprFact::illegalOpr, x->monitor_no()); }
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -1031,3 +1031,7 @@ #undef __ #define __ masm-> + +const char *Runtime1::pd_name_for_address(address entry) { + return "<unknown function>"; +}
--- a/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -56,14 +56,18 @@ } -#ifdef _LP64 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { Argument jni_arg(jni_offset(), false); +#ifdef _LP64 FloatRegister Rtmp = F0; __ ldf(FloatRegisterImpl::S, Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp); __ store_float_argument(Rtmp, jni_arg); +#else + Register Rtmp = O0; + __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp); + __ store_argument(Rtmp, jni_arg); +#endif } -#endif void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { @@ -185,6 +189,13 @@ _from -= 2*Interpreter::stackElementSize; add_signature( non_float ); } + + virtual void pass_float() { + *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); + _from -= Interpreter::stackElementSize; + add_signature( non_float ); + } + #endif // _LP64 virtual void add_signature( intptr_t sig_type ) {
--- a/hotspot/src/cpu/sparc/vm/javaFrameAnchor_sparc.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/javaFrameAnchor_sparc.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -76,6 +76,8 @@ void set_last_Java_sp(intptr_t* sp) { _last_Java_sp = sp; } + address last_Java_pc(void) { return _last_Java_pc; } + // These are only used by friends private:
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -3236,12 +3236,14 @@ __ get_2_byte_integer_at_bcp(1, Rscratch, Roffset, InterpreterMacroAssembler::Unsigned); __ get_cpool_and_tags(Rscratch, G3_scratch); // make sure the class we're about to instantiate has been resolved + // This is done before loading instanceKlass to be consistent with the order + // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put) __ add(G3_scratch, typeArrayOopDesc::header_size(T_BYTE) * wordSize, G3_scratch); __ ldub(G3_scratch, Roffset, G3_scratch); __ cmp(G3_scratch, JVM_CONSTANT_Class); __ br(Assembler::notEqual, false, Assembler::pn, slow_case); __ delayed()->sll(Roffset, LogBytesPerWord, Roffset); - + // get instanceKlass //__ sll(Roffset, LogBytesPerWord, Roffset); // executed in delay slot __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); __ ld_ptr(Rscratch, Roffset, RinstanceKlass);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -7151,7 +7151,7 @@ subptr(t1, typeArrayOopDesc::header_size(T_INT)); addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint))); - movptr(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); + movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); // set klass to intArrayKlass // dubious reloc why not an oop reloc? movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); @@ -7568,21 +7568,27 @@ // Scan RCX words at [RDI] for an occurrence of RAX. // Set NZ/Z based on last compare. + // Z flag value will not be set by 'repne' if RCX == 0 since 'repne' does + // not change flags (only scas instruction which is repeated sets flags). + // Set Z = 0 (not equal) before 'repne' to indicate that class was not found. #ifdef _LP64 // This part is tricky, as values in supers array could be 32 or 64 bit wide // and we store values in objArrays always encoded, thus we need to encode // the value of rax before repne. Note that rax is dead after the repne. if (UseCompressedOops) { - encode_heap_oop_not_null(rax); + encode_heap_oop_not_null(rax); // Changes flags. // The superclass is never null; it would be a basic system error if a null // pointer were to sneak in here. Note that we have already loaded the // Klass::super_check_offset from the super_klass in the fast path, // so if there is a null in that register, we are already in the afterlife. + testl(rax,rax); // Set Z = 0 repne_scanl(); } else #endif // _LP64 + { + testptr(rax,rax); // Set Z = 0 repne_scan(); - + } // Unspill the temp. registers: if (pushed_rdi) pop(rdi); if (pushed_rcx) pop(rcx); @@ -8257,30 +8263,35 @@ } } +#ifdef ASSERT +void MacroAssembler::verify_heapbase(const char* msg) { + assert (UseCompressedOops, "should be compressed"); + assert (Universe::heap() != NULL, "java heap should be initialized"); + if (CheckCompressedOops) { + Label ok; + push(rscratch1); // cmpptr trashes rscratch1 + cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); + jcc(Assembler::equal, ok); + stop(msg); + bind(ok); + pop(rscratch1); + } +} +#endif + // Algorithm must match oop.inline.hpp encode_heap_oop. void MacroAssembler::encode_heap_oop(Register r) { - assert (UseCompressedOops, "should be compressed"); - assert (Universe::heap() != NULL, "java heap should be initialized"); +#ifdef ASSERT + verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?"); +#endif + verify_oop(r, "broken oop in encode_heap_oop"); if (Universe::narrow_oop_base() == NULL) { - verify_oop(r, "broken oop in encode_heap_oop"); if (Universe::narrow_oop_shift() != 0) { assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); shrq(r, LogMinObjAlignmentInBytes); } return; } -#ifdef ASSERT - if (CheckCompressedOops) { - Label ok; - push(rscratch1); // cmpptr trashes rscratch1 - cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); - jcc(Assembler::equal, ok); - stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); - bind(ok); - pop(rscratch1); - } -#endif - verify_oop(r, "broken oop in encode_heap_oop"); testq(r, r); cmovq(Assembler::equal, r, r12_heapbase); subq(r, r12_heapbase); @@ -8288,9 +8299,8 @@ } void MacroAssembler::encode_heap_oop_not_null(Register r) { - assert (UseCompressedOops, "should be compressed"); - assert (Universe::heap() != NULL, "java heap should be initialized"); #ifdef ASSERT + verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?"); if (CheckCompressedOops) { Label ok; testq(r, r); @@ -8310,9 +8320,8 @@ } void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { - assert (UseCompressedOops, "should be compressed"); - assert (Universe::heap() != NULL, "java heap should be initialized"); #ifdef ASSERT + verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?"); if (CheckCompressedOops) { Label ok; testq(src, src); @@ -8335,40 +8344,21 @@ } void MacroAssembler::decode_heap_oop(Register r) { - assert (UseCompressedOops, "should be compressed"); - assert (Universe::heap() != NULL, "java heap should be initialized"); +#ifdef ASSERT + verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?"); +#endif if (Universe::narrow_oop_base() == NULL) { if (Universe::narrow_oop_shift() != 0) { assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); shlq(r, LogMinObjAlignmentInBytes); } - verify_oop(r, "broken oop in decode_heap_oop"); - return; - } -#ifdef ASSERT - if (CheckCompressedOops) { - Label ok; - push(rscratch1); - cmpptr(r12_heapbase, - ExternalAddress((address)Universe::narrow_oop_base_addr())); - jcc(Assembler::equal, ok); - stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); - bind(ok); - pop(rscratch1); - } -#endif - - Label done; - shlq(r, LogMinObjAlignmentInBytes); - jccb(Assembler::equal, done); - addq(r, r12_heapbase); -#if 0 - // alternate decoding probably a wash. - testq(r, r); - jccb(Assembler::equal, done); - leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); -#endif - bind(done); + } else { + Label done; + shlq(r, LogMinObjAlignmentInBytes); + jccb(Assembler::equal, done); + addq(r, r12_heapbase); + bind(done); + } verify_oop(r, "broken oop in decode_heap_oop"); } @@ -8410,9 +8400,11 @@ addq(dst, r12_heapbase); } } - } else if (dst != src) { + } else { assert (Universe::narrow_oop_base() == NULL, "sanity"); - movq(dst, src); + if (dst != src) { + movq(dst, src); + } } }
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -1714,6 +1714,9 @@ // if heap base register is used - reinit it with the correct value void reinit_heapbase(); + + DEBUG_ONLY(void verify_heapbase(const char* msg);) + #endif // _LP64 // Int division/remainder for Java
--- a/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -236,11 +236,11 @@ } inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) { - return op1 << op2; + return op1 << op2; } inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) { - return op1 >> op2; // QQ op2 & 0x1f?? + return op1 >> (op2 & 0x1f); } inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) { @@ -248,7 +248,7 @@ } inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { - return ((juint) op1) >> op2; // QQ op2 & 0x1f?? + return ((juint) op1) >> (op2 & 0x1f); } inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -349,7 +349,7 @@ LIR_Opr lock = new_register(T_INT); LIR_Opr obj_temp = new_register(T_INT); set_no_result(x); - monitor_exit(obj_temp, lock, syncTempOpr(), x->monitor_no()); + monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no()); }
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -1779,3 +1779,7 @@ } #undef __ + +const char *Runtime1::pd_name_for_address(address entry) { + return "<unknown function>"; +}
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -575,8 +575,8 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { #ifdef CC_INTERP - // Needed for JVMTI. The result should always be in the interpreterState object - assert(false, "NYI"); + // Needed for JVMTI. The result should always be in the + // interpreterState object interpreterState istate = get_interpreterState(); #endif // CC_INTERP assert(is_interpreted_frame(), "interpreted frame expected");
--- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -34,6 +34,10 @@ move(offset(), jni_offset() + 1); } +void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { + move(offset(), jni_offset() + 1); +} + void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { move(offset(), jni_offset() + 2); move(offset() + 1, jni_offset() + 1); @@ -91,6 +95,11 @@ _from -= Interpreter::stackElementSize; } + virtual void pass_float() { + *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); + _from -= Interpreter::stackElementSize; + } + virtual void pass_long() { _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
--- a/hotspot/src/cpu/x86/vm/javaFrameAnchor_x86.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/javaFrameAnchor_x86.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -66,6 +66,8 @@ intptr_t* last_Java_sp(void) const { return _last_Java_sp; } + address last_Java_pc(void) { return _last_Java_pc; } + private: static ByteSize last_Java_fp_offset() { return byte_offset_of(JavaFrameAnchor, _last_Java_fp); }
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -3112,22 +3112,25 @@ transition(vtos, atos); __ get_unsigned_2_byte_index_at_bcp(rdx, 1); Label slow_case; + Label slow_case_no_pop; Label done; Label initialize_header; Label initialize_object; // including clearing the fields Label allocate_shared; __ get_cpool_and_tags(rcx, rax); + + // Make sure the class we're about to instantiate has been resolved. + // This is done before loading instanceKlass to be consistent with the order + // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put) + const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; + __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class); + __ jcc(Assembler::notEqual, slow_case_no_pop); + // get instanceKlass __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc))); __ push(rcx); // save the contexts of klass for initializing the header - // make sure the class we're about to instantiate has been resolved. - // Note: slow_case does a pop of stack, which is why we loaded class/pushed above - const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; - __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class); - __ jcc(Assembler::notEqual, slow_case); - // make sure klass is initialized & doesn't have finalizer // make sure klass is fully initialized __ cmpl(Address(rcx, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); @@ -3255,6 +3258,7 @@ // slow case __ bind(slow_case); __ pop(rcx); // restore stack pointer to what it was when we came in. + __ bind(slow_case_no_pop); __ get_constant_pool(rax); __ get_unsigned_2_byte_index_at_bcp(rdx, 1); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), rax, rdx);
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -3126,18 +3126,18 @@ Label allocate_shared; __ get_cpool_and_tags(rsi, rax); - // get instanceKlass - __ movptr(rsi, Address(rsi, rdx, - Address::times_8, sizeof(constantPoolOopDesc))); - - // make sure the class we're about to instantiate has been - // resolved. Note: slow_case does a pop of stack, which is why we - // loaded class/pushed above + // Make sure the class we're about to instantiate has been resolved. + // This is done before loading instanceKlass to be consistent with the order + // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put) const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class); __ jcc(Assembler::notEqual, slow_case); + // get instanceKlass + __ movptr(rsi, Address(rsi, rdx, + Address::times_8, sizeof(constantPoolOopDesc))); + // make sure klass is initialized & doesn't have finalizer // make sure klass is fully initialized __ cmpl(Address(rsi,
--- a/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007 Red Hat, Inc. + * Copyright 2007, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,10 @@ * */ -// The disassembler prints out zero code annotated -// with Java specific information. - static int pd_instruction_alignment() { - ShouldNotCallThis(); + return 1; } static const char* pd_cpu_opts() { - ShouldNotCallThis(); + return ""; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009, 2010 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// Set the default values for platform dependent flags used by the +// Shark compiler. See globals.hpp for details of what they do. + +define_pd_global(bool, BackgroundCompilation, true ); +define_pd_global(bool, UseTLAB, true ); +define_pd_global(bool, ResizeTLAB, true ); +define_pd_global(bool, InlineIntrinsics, false); +define_pd_global(bool, PreferInterpreterNativeStubs, false); +define_pd_global(bool, ProfileTraps, false); +define_pd_global(bool, UseOnStackReplacement, true ); +define_pd_global(bool, TieredCompilation, false); + +define_pd_global(intx, CompileThreshold, 1500); +define_pd_global(intx, Tier2CompileThreshold, 1500); +define_pd_global(intx, Tier3CompileThreshold, 2500); +define_pd_global(intx, Tier4CompileThreshold, 4500); + +define_pd_global(intx, BackEdgeThreshold, 100000); +define_pd_global(intx, Tier2BackEdgeThreshold, 100000); +define_pd_global(intx, Tier3BackEdgeThreshold, 100000); +define_pd_global(intx, Tier4BackEdgeThreshold, 100000); + +define_pd_global(intx, OnStackReplacePercentage, 933 ); +define_pd_global(intx, FreqInlineSize, 325 ); +define_pd_global(intx, InlineSmallCode, 1000 ); +define_pd_global(intx, NewRatio, 12 ); +define_pd_global(intx, NewSizeThreadIncrease, 4*K ); +define_pd_global(intx, InitialCodeCacheSize, 160*K); +define_pd_global(intx, ReservedCodeCacheSize, 32*M ); +define_pd_global(bool, ProfileInterpreter, false); +define_pd_global(intx, CodeCacheExpansionSize, 32*K ); +define_pd_global(uintx, CodeCacheMinBlockLength, 1 ); +define_pd_global(uintx, PermSize, 12*M ); +define_pd_global(uintx, MaxPermSize, 64*M ); +define_pd_global(bool, NeverActAsServerClassMachine, true ); +define_pd_global(uint64_t, MaxRAM, 1ULL*G); +define_pd_global(bool, CICompileOSR, true );
--- a/hotspot/src/os/linux/launcher/java_md.c Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os/linux/launcher/java_md.c Thu Sep 02 22:11:05 2010 -0700 @@ -79,6 +79,10 @@ # define ARCH "i386" # elif defined(__sparc) # define ARCH "sparc" +# elif defined(arm) +# define ARCH "arm" +# elif defined(PPC) +# define ARCH "ppc" # endif #endif /* _LP64 */
--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -32,11 +32,15 @@ #include <sys/un.h> #include <sys/stat.h> +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path) +#endif + // The attach mechanism on Linux uses a UNIX domain socket. An attach listener // thread is created at startup or is created on-demand via a signal from // the client tool. The attach listener creates a socket and binds it to a file // in the filesystem. The attach listener then acts as a simple (single- -// threaded) server - tt waits for a client to connect, reads the request, +// threaded) server - it waits for a client to connect, reads the request, // executes it, and returns the response to the client via the socket // connection. // @@ -54,7 +58,7 @@ class LinuxAttachListener: AllStatic { private: // the path to which we bind the UNIX domain socket - static char _path[PATH_MAX+1]; + static char _path[UNIX_PATH_MAX]; static bool _has_path; // the file descriptor for the listening socket @@ -64,8 +68,8 @@ if (path == NULL) { _has_path = false; } else { - strncpy(_path, path, PATH_MAX); - _path[PATH_MAX] = '\0'; + strncpy(_path, path, UNIX_PATH_MAX); + _path[UNIX_PATH_MAX-1] = '\0'; _has_path = true; } } @@ -113,7 +117,7 @@ }; // statics -char LinuxAttachListener::_path[PATH_MAX+1]; +char LinuxAttachListener::_path[UNIX_PATH_MAX]; bool LinuxAttachListener::_has_path; int LinuxAttachListener::_listener = -1; @@ -163,54 +167,53 @@ // Initialization - create a listener socket and bind it to a file int LinuxAttachListener::init() { - char path[PATH_MAX+1]; // socket file - int listener; // listener socket (file descriptor) + char path[UNIX_PATH_MAX]; // socket file + char initial_path[UNIX_PATH_MAX]; // socket file during setup + int listener; // listener socket (file descriptor) // register function to cleanup ::atexit(listener_cleanup); + int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d", + os::get_temp_directory(), os::current_process_id()); + if (n <= (int)UNIX_PATH_MAX) { + n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path); + } + if (n > (int)UNIX_PATH_MAX) { + return -1; + } + // create the listener socket listener = ::socket(PF_UNIX, SOCK_STREAM, 0); if (listener == -1) { return -1; } - int res = -1; + // bind socket struct sockaddr_un addr; addr.sun_family = AF_UNIX; - - // FIXME: Prior to b39 the tool-side API expected to find the well - // known file in the working directory. To allow this libjvm.so work with - // a pre-b39 SDK we create it in the working directory if - // +StartAttachListener is used is used. All unit tests for this feature - // currently used this flag. Once b39 SDK has been promoted we can remove - // this code. - if (StartAttachListener) { - sprintf(path, ".java_pid%d", os::current_process_id()); - strcpy(addr.sun_path, path); - ::unlink(path); - res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr)); - } - if (res == -1) { - snprintf(path, PATH_MAX+1, "%s/.java_pid%d", - os::get_temp_directory(), os::current_process_id()); - strcpy(addr.sun_path, path); - ::unlink(path); - res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr)); - } + strcpy(addr.sun_path, initial_path); + ::unlink(initial_path); + int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr)); if (res == -1) { RESTARTABLE(::close(listener), res); return -1; } - set_path(path); - // put in listen mode and set permission - if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) { + // put in listen mode, set permissions, and rename into place + res = ::listen(listener, 5); + if (res == 0) { + RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res); + if (res == 0) { + res = ::rename(initial_path, path); + } + } + if (res == -1) { RESTARTABLE(::close(listener), res); - ::unlink(path); - set_path(NULL); + ::unlink(initial_path); return -1; } + set_path(path); set_listener(listener); return 0;
--- a/hotspot/src/os/linux/vm/globals_linux.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os/linux/vm/globals_linux.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -29,9 +29,10 @@ product(bool, UseOprofile, false, \ "enable support for Oprofile profiler") \ \ - product(bool, UseLinuxPosixThreadCPUClocks, false, \ - "enable fast Linux Posix clocks where available") \ - + product(bool, UseLinuxPosixThreadCPUClocks, true, \ + "enable fast Linux Posix clocks where available") +// NB: The default value of UseLinuxPosixThreadCPUClocks may be +// overridden in Arguments::parse_each_vm_init_arg. // // Defines Linux-specific default values. The flags are available on all
--- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -30,6 +30,8 @@ // put OS-includes here # include <sys/types.h> # include <sys/mman.h> +# include <sys/stat.h> +# include <sys/select.h> # include <pthread.h> # include <signal.h> # include <errno.h> @@ -188,6 +190,10 @@ static char cpu_arch[] = "i386"; #elif defined(AMD64) static char cpu_arch[] = "amd64"; +#elif defined(ARM) +static char cpu_arch[] = "arm"; +#elif defined(PPC) +static char cpu_arch[] = "ppc"; #elif defined(SPARC) # ifdef _LP64 static char cpu_arch[] = "sparcv9"; @@ -1137,8 +1143,8 @@ long it_real; uintptr_t start; uintptr_t vsize; - uintptr_t rss; - unsigned long rsslim; + intptr_t rss; + uintptr_t rsslim; uintptr_t scodes; uintptr_t ecode; int i; @@ -1168,12 +1174,12 @@ // Skip blank chars do s++; while (isspace(*s)); - /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ - /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */ - i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " - UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT - " %lu " - UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT, +#define _UFM UINTX_FORMAT +#define _DFM INTX_FORMAT + + /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ + /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */ + i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM, &state, /* 3 %c */ &ppid, /* 4 %d */ &pgrp, /* 5 %d */ @@ -1193,15 +1199,18 @@ &nice, /* 19 %ld */ &junk, /* 20 %ld */ &it_real, /* 21 %ld */ - &start, /* 22 UINTX_FORMAT */ - &vsize, /* 23 UINTX_FORMAT */ - &rss, /* 24 UINTX_FORMAT */ - &rsslim, /* 25 %lu */ - &scodes, /* 26 UINTX_FORMAT */ - &ecode, /* 27 UINTX_FORMAT */ - &stack_start); /* 28 UINTX_FORMAT */ + &start, /* 22 UINTX_FORMAT */ + &vsize, /* 23 UINTX_FORMAT */ + &rss, /* 24 INTX_FORMAT */ + &rsslim, /* 25 UINTX_FORMAT */ + &scodes, /* 26 UINTX_FORMAT */ + &ecode, /* 27 UINTX_FORMAT */ + &stack_start); /* 28 UINTX_FORMAT */ } +#undef _UFM +#undef _DFM + if (i != 28 - 2) { assert(false, "Bad conversion from /proc/self/stat"); // product mode - assume we are the initial thread, good luck in the @@ -1336,14 +1345,16 @@ #if defined(IA32) || defined(AMD64) #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229) +#define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) #else -#error Value of SYS_clock_getres not known on this platform +#warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time" +#define sys_clock_getres(x,y) -1 #endif +#else +#define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) #endif -#define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) - void os::Linux::fast_thread_clock_init() { if (!UseLinuxPosixThreadCPUClocks) { return; @@ -1905,7 +1916,9 @@ !_print_ascii_file("/etc/SuSE-release", st) && !_print_ascii_file("/etc/turbolinux-release", st) && !_print_ascii_file("/etc/gentoo-release", st) && - !_print_ascii_file("/etc/debian_version", st)) { + !_print_ascii_file("/etc/debian_version", st) && + !_print_ascii_file("/etc/ltib-release", st) && + !_print_ascii_file("/etc/angstrom-version", st)) { st->print("Linux"); } st->cr(); @@ -1971,6 +1984,11 @@ os::loadavg(loadavg, 3); st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); st->cr(); + + // meminfo + st->print("\n/proc/meminfo:\n"); + _print_ascii_file("/proc/meminfo", st); + st->cr(); } void os::print_memory_info(outputStream* st) { @@ -2097,7 +2115,8 @@ CAST_FROM_FN_PTR(address, os::jvm_path), dli_fname, sizeof(dli_fname), NULL); assert(ret != 0, "cannot locate libjvm"); - if (realpath(dli_fname, buf) == NULL) + char *rp = realpath(dli_fname, buf); + if (rp == NULL) return; if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { @@ -2125,7 +2144,8 @@ assert(strstr(p, "/libjvm") == p, "invalid library name"); p = strstr(p, "_g") ? "_g" : ""; - if (realpath(java_home_var, buf) == NULL) + rp = realpath(java_home_var, buf); + if (rp == NULL) return; // determine if this is a legacy image or modules image @@ -2147,7 +2167,8 @@ snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); } else { // Go back to path of .so - if (realpath(dli_fname, buf) == NULL) + rp = realpath(dli_fname, buf); + if (rp == NULL) return; } } @@ -2508,9 +2529,9 @@ unsigned long* os::Linux::_numa_all_nodes; bool os::uncommit_memory(char* addr, size_t size) { - return ::mmap(addr, size, PROT_NONE, - MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) - != MAP_FAILED; + uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, + MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); + return res != (uintptr_t) MAP_FAILED; } // Linux uses a growable mapping for the stack, and if the mapping for @@ -2718,7 +2739,8 @@ // the processor. #ifndef ZERO - _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M); + _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M) + ARM_ONLY(2 * M) PPC_ONLY(4 * M); #endif // ZERO FILE *fp = fopen("/proc/meminfo", "r"); @@ -3981,6 +4003,9 @@ return JNI_OK; } +// this is called at the end of vm_initialization +void os::init_3(void) { } + // Mark the polling page as unreadable void os::make_polling_page_unreadable(void) { if( !guard_memory((char*)_polling_page, Linux::page_size()) ) @@ -4061,7 +4086,6 @@ //////////////////////////////////////////////////////////////////////////////// // debug support -#ifndef PRODUCT static address same_page(address x, address y) { int page_bits = -os::vm_page_size(); if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) @@ -4072,26 +4096,26 @@ return (address)(intptr_t(y) & page_bits); } -bool os::find(address addr) { +bool os::find(address addr, outputStream* st) { Dl_info dlinfo; memset(&dlinfo, 0, sizeof(dlinfo)); if (dladdr(addr, &dlinfo)) { - tty->print(PTR_FORMAT ": ", addr); + st->print(PTR_FORMAT ": ", addr); if (dlinfo.dli_sname != NULL) { - tty->print("%s+%#x", dlinfo.dli_sname, + st->print("%s+%#x", dlinfo.dli_sname, addr - (intptr_t)dlinfo.dli_saddr); } else if (dlinfo.dli_fname) { - tty->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); + st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); } else { - tty->print("<absolute address>"); + st->print("<absolute address>"); } if (dlinfo.dli_fname) { - tty->print(" in %s", dlinfo.dli_fname); + st->print(" in %s", dlinfo.dli_fname); } if (dlinfo.dli_fbase) { - tty->print(" at " PTR_FORMAT, dlinfo.dli_fbase); + st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); } - tty->cr(); + st->cr(); if (Verbose) { // decode some bytes around the PC @@ -4104,15 +4128,13 @@ if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) end = (address) dlinfo2.dli_saddr; - Disassembler::decode(begin, end); + Disassembler::decode(begin, end, st); } return true; } return false; } -#endif - //////////////////////////////////////////////////////////////////////////////// // misc @@ -4321,6 +4343,7 @@ int count; long sys_time, user_time; char string[64]; + char cdummy; int idummy; long ldummy; FILE *fp; @@ -4381,11 +4404,11 @@ // Skip blank chars do s++; while (isspace(*s)); - count = sscanf(s,"%*c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", - &idummy, &idummy, &idummy, &idummy, &idummy, + count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", + &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy, &ldummy, &ldummy, &ldummy, &ldummy, &ldummy, &user_time, &sys_time); - if ( count != 12 ) return -1; + if ( count != 13 ) return -1; if (user_sys_cpu_time) { return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); } else { @@ -4980,3 +5003,43 @@ } } } + +// is_headless_jre() +// +// Test for the existence of libmawt in motif21 or xawt directories +// in order to report if we are running in a headless jre +// +bool os::is_headless_jre() { + struct stat statbuf; + char buf[MAXPATHLEN]; + char libmawtpath[MAXPATHLEN]; + const char *xawtstr = "/xawt/libmawt.so"; + const char *motifstr = "/motif21/libmawt.so"; + char *p; + + // Get path to libjvm.so + os::jvm_path(buf, sizeof(buf)); + + // Get rid of libjvm.so + p = strrchr(buf, '/'); + if (p == NULL) return false; + else *p = '\0'; + + // Get rid of client or server + p = strrchr(buf, '/'); + if (p == NULL) return false; + else *p = '\0'; + + // check xawt/libmawt.so + strcpy(libmawtpath, buf); + strcat(libmawtpath, xawtstr); + if (::stat(libmawtpath, &statbuf) == 0) return false; + + // check motif21/libmawt.so + strcpy(libmawtpath, buf); + strcat(libmawtpath, motifstr); + if (::stat(libmawtpath, &statbuf) == 0) return false; + + return true; +} +
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -364,6 +364,7 @@ // Create the door int SolarisAttachListener::create_door() { char door_path[PATH_MAX+1]; + char initial_path[PATH_MAX+1]; int fd, res; // register exit function @@ -375,36 +376,46 @@ return -1; } + // create initial file to attach door descriptor snprintf(door_path, sizeof(door_path), "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id()); - RESTARTABLE(::creat(door_path, S_IRUSR | S_IWUSR), fd); - + snprintf(initial_path, sizeof(initial_path), "%s.tmp", door_path); + RESTARTABLE(::creat(initial_path, S_IRUSR | S_IWUSR), fd); if (fd == -1) { - debug_only(warning("attempt to create %s failed", door_path)); + debug_only(warning("attempt to create %s failed", initial_path)); + ::door_revoke(dd); return -1; } assert(fd >= 0, "bad file descriptor"); - set_door_path(door_path); RESTARTABLE(::close(fd), res); // attach the door descriptor to the file - if ((res = ::fattach(dd, door_path)) == -1) { + if ((res = ::fattach(dd, initial_path)) == -1) { // if busy then detach and try again if (errno == EBUSY) { - ::fdetach(door_path); - res = ::fattach(dd, door_path); + ::fdetach(initial_path); + res = ::fattach(dd, initial_path); } if (res == -1) { ::door_revoke(dd); dd = -1; } } + + // rename file so that clients can attach + if (dd >= 0) { + if (::rename(initial_path, door_path) == -1) { + RESTARTABLE(::close(dd), res); + ::fdetach(initial_path); + dd = -1; + } + } if (dd >= 0) { set_door_descriptor(dd); + set_door_path(door_path); } else { - // unable to create door or attach it to the file - ::unlink(door_path); - set_door_path(NULL); + // unable to create door, attach it to file, or rename file into place + ::unlink(initial_path); return -1; }
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -1839,8 +1839,8 @@ // Quietly truncate on buffer overflow. Should be an error. if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { - *buffer = '\0'; - return; + *buffer = '\0'; + return; } if (pnamelen == 0) { @@ -2051,7 +2051,8 @@ {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, - {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"} + {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, + {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM 32"} }; #if (defined IA32) @@ -2068,9 +2069,11 @@ static Elf32_Half running_arch_code=EM_PPC64; #elif (defined __powerpc__) static Elf32_Half running_arch_code=EM_PPC; + #elif (defined ARM) + static Elf32_Half running_arch_code=EM_ARM; #else #error Method os::dll_load requires that one of following is defined:\ - IA32, AMD64, IA64, __sparc, __powerpc__ + IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM #endif // Identify compatability class for VM's architecture and library's architecture @@ -3149,7 +3152,8 @@ // ISM is only recommended on old Solaris where there is no MPSS support. // Simply choose a conservative value as default. *page_size = LargePageSizeInBytes ? LargePageSizeInBytes : - SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M); + SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M) + ARM_ONLY(2 * M); // ISM is available on all supported Solaris versions return true; @@ -5007,6 +5011,9 @@ return JNI_OK; } +void os::init_3(void) { + return; +} // Mark the polling page as unreadable void os::make_polling_page_unreadable(void) { @@ -5412,7 +5419,6 @@ } //--------------------------------------------------------------------------------- -#ifndef PRODUCT static address same_page(address x, address y) { intptr_t page_bits = -os::vm_page_size(); @@ -5424,28 +5430,28 @@ return (address)(intptr_t(y) & page_bits); } -bool os::find(address addr) { +bool os::find(address addr, outputStream* st) { Dl_info dlinfo; memset(&dlinfo, 0, sizeof(dlinfo)); if (dladdr(addr, &dlinfo)) { #ifdef _LP64 - tty->print("0x%016lx: ", addr); + st->print("0x%016lx: ", addr); #else - tty->print("0x%08x: ", addr); + st->print("0x%08x: ", addr); #endif if (dlinfo.dli_sname != NULL) - tty->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr); + st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr); else if (dlinfo.dli_fname) - tty->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase); + st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase); else - tty->print("<absolute address>"); - if (dlinfo.dli_fname) tty->print(" in %s", dlinfo.dli_fname); + st->print("<absolute address>"); + if (dlinfo.dli_fname) st->print(" in %s", dlinfo.dli_fname); #ifdef _LP64 - if (dlinfo.dli_fbase) tty->print(" at 0x%016lx", dlinfo.dli_fbase); + if (dlinfo.dli_fbase) st->print(" at 0x%016lx", dlinfo.dli_fbase); #else - if (dlinfo.dli_fbase) tty->print(" at 0x%08x", dlinfo.dli_fbase); + if (dlinfo.dli_fbase) st->print(" at 0x%08x", dlinfo.dli_fbase); #endif - tty->cr(); + st->cr(); if (Verbose) { // decode some bytes around the PC @@ -5458,16 +5464,13 @@ if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) end = (address) dlinfo2.dli_saddr; - Disassembler::decode(begin, end); + Disassembler::decode(begin, end, st); } return true; } return false; } -#endif - - // Following function has been added to support HotSparc's libjvm.so running // under Solaris production JDK 1.2.2 / 1.3.0. These came from // src/solaris/hpi/native_threads in the EVM codebase. @@ -5910,7 +5913,6 @@ if (jt->handle_special_suspend_equivalent_condition()) { jt->java_suspend_self(); } - OrderAccess::fence(); } @@ -5997,3 +5999,44 @@ } } } + +// is_headless_jre() +// +// Test for the existence of libmawt in motif21 or xawt directories +// in order to report if we are running in a headless jre +// +bool os::is_headless_jre() { + struct stat statbuf; + char buf[MAXPATHLEN]; + char libmawtpath[MAXPATHLEN]; + const char *xawtstr = "/xawt/libmawt.so"; + const char *motifstr = "/motif21/libmawt.so"; + char *p; + + // Get path to libjvm.so + os::jvm_path(buf, sizeof(buf)); + + // Get rid of libjvm.so + p = strrchr(buf, '/'); + if (p == NULL) return false; + else *p = '\0'; + + // Get rid of client or server + p = strrchr(buf, '/'); + if (p == NULL) return false; + else *p = '\0'; + + // check xawt/libmawt.so + strcpy(libmawtpath, buf); + strcat(libmawtpath, xawtstr); + if (::stat(libmawtpath, &statbuf) == 0) return false; + + // check motif21/libmawt.so + strcpy(libmawtpath, buf); + strcat(libmawtpath, motifstr); + if (::stat(libmawtpath, &statbuf) == 0) return false; + + return true; +} + +
--- a/hotspot/src/os/windows/vm/os_windows.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -3444,6 +3444,9 @@ return JNI_OK; } +void os::init_3(void) { + return; +} // Mark the polling page as unreadable void os::make_polling_page_unreadable(void) { @@ -4105,12 +4108,10 @@ } -#ifndef PRODUCT -bool os::find(address addr) { +bool os::find(address addr, outputStream* st) { // Nothing yet return false; } -#endif LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) { DWORD exception_code = e->ExceptionRecord->ExceptionCode; @@ -4164,3 +4165,8 @@ } return 0; } + + +// We don't build a headless jre for Windows +bool os::is_headless_jre() { return false; } +
--- a/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -105,3 +105,6 @@ // nothing else to try return false; } + +void JavaThread::cache_global_variables() { } +
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -718,6 +718,11 @@ ucontext_t *uc = (ucontext_t*)context; st->print_cr("Registers:"); + + // this is horrendously verbose but the layout of the registers in the + // context does not match how we defined our abstract Register set, so + // we can't just iterate through the gregs area + #ifdef AMD64 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); @@ -745,6 +750,63 @@ st->print(", ERR=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ERR]); st->cr(); st->print(" TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]); + + st->cr(); + st->cr(); + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is only for the "general purpose" registers + + st->print_cr("RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); + print_location(st, uc->uc_mcontext.gregs[REG_RAX]); + st->cr(); + st->print_cr("RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); + print_location(st, uc->uc_mcontext.gregs[REG_RBX]); + st->cr(); + st->print_cr("RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); + print_location(st, uc->uc_mcontext.gregs[REG_RCX]); + st->cr(); + st->print_cr("RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]); + print_location(st, uc->uc_mcontext.gregs[REG_RDX]); + st->cr(); + st->print_cr("RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]); + print_location(st, uc->uc_mcontext.gregs[REG_RSP]); + st->cr(); + st->print_cr("RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]); + print_location(st, uc->uc_mcontext.gregs[REG_RBP]); + st->cr(); + st->print_cr("RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]); + print_location(st, uc->uc_mcontext.gregs[REG_RSI]); + st->cr(); + st->print_cr("RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]); + print_location(st, uc->uc_mcontext.gregs[REG_RDI]); + st->cr(); + st->print_cr("R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); + print_location(st, uc->uc_mcontext.gregs[REG_R8]); + st->cr(); + st->print_cr("R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]); + print_location(st, uc->uc_mcontext.gregs[REG_R9]); + st->cr(); + st->print_cr("R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]); + print_location(st, uc->uc_mcontext.gregs[REG_R10]); + st->cr(); + st->print_cr("R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]); + print_location(st, uc->uc_mcontext.gregs[REG_R11]); + st->cr(); + st->print_cr("R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); + print_location(st, uc->uc_mcontext.gregs[REG_R12]); + st->cr(); + st->print_cr("R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]); + print_location(st, uc->uc_mcontext.gregs[REG_R13]); + st->cr(); + st->print_cr("R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]); + print_location(st, uc->uc_mcontext.gregs[REG_R14]); + st->cr(); + st->print_cr("R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]); + print_location(st, uc->uc_mcontext.gregs[REG_R15]); + #else st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]); st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]); @@ -759,6 +821,39 @@ st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]); st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2); st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]); + + st->cr(); + st->cr(); + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is only for the "general purpose" registers + + st->print_cr("EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]); + print_location(st, uc->uc_mcontext.gregs[REG_EAX]); + st->cr(); + st->print_cr("EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]); + print_location(st, uc->uc_mcontext.gregs[REG_EBX]); + st->cr(); + st->print_cr("ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ECX]); + print_location(st, uc->uc_mcontext.gregs[REG_ECX]); + st->cr(); + st->print_cr("EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDX]); + print_location(st, uc->uc_mcontext.gregs[REG_EDX]); + st->cr(); + st->print_cr("ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESP]); + print_location(st, uc->uc_mcontext.gregs[REG_ESP]); + st->cr(); + st->print_cr("EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBP]); + print_location(st, uc->uc_mcontext.gregs[REG_EBP]); + st->cr(); + st->print_cr("ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESI]); + print_location(st, uc->uc_mcontext.gregs[REG_ESI]); + st->cr(); + st->print_cr("EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]); + print_location(st, uc->uc_mcontext.gregs[REG_EDI]); + #endif // AMD64 st->cr(); st->cr();
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -79,3 +79,6 @@ // nothing else to try return false; } + +void JavaThread::cache_global_variables() { } +
--- a/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -24,3 +24,5 @@ */ // This file is intentionally empty + +void JavaThread::cache_global_variables() { }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -587,6 +587,61 @@ st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_PC], uc->uc_mcontext.gregs[REG_nPC]); + + st->cr(); + st->cr(); + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is only for the "general purpose" registers + + st->print_cr("O0=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O0]); + print_location(st, uc->uc_mcontext.gregs[REG_O0]); + st->cr(); + st->print_cr("O1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O1]); + print_location(st, uc->uc_mcontext.gregs[REG_O1]); + st->cr(); + st->print_cr("O2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O2]); + print_location(st, uc->uc_mcontext.gregs[REG_O2]); + st->cr(); + st->print_cr("O3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O3]); + print_location(st, uc->uc_mcontext.gregs[REG_O3]); + st->cr(); + st->print_cr("O4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O4]); + print_location(st, uc->uc_mcontext.gregs[REG_O4]); + st->cr(); + st->print_cr("O5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O5]); + print_location(st, uc->uc_mcontext.gregs[REG_O5]); + st->cr(); + st->print_cr("O6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O6]); + print_location(st, uc->uc_mcontext.gregs[REG_O6]); + st->cr(); + st->print_cr("O7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O7]); + print_location(st, uc->uc_mcontext.gregs[REG_O7]); + st->cr(); + + st->print_cr("G1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G1]); + print_location(st, uc->uc_mcontext.gregs[REG_G1]); + st->cr(); + st->print_cr("G2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G2]); + print_location(st, uc->uc_mcontext.gregs[REG_G2]); + st->cr(); + st->print_cr("G3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G3]); + print_location(st, uc->uc_mcontext.gregs[REG_G3]); + st->cr(); + st->print_cr("G4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G4]); + print_location(st, uc->uc_mcontext.gregs[REG_G4]); + st->cr(); + st->print_cr("G5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G5]); + print_location(st, uc->uc_mcontext.gregs[REG_G5]); + st->cr(); + st->print_cr("G6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G6]); + print_location(st, uc->uc_mcontext.gregs[REG_G6]); + st->cr(); + st->print_cr("G7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G7]); + print_location(st, uc->uc_mcontext.gregs[REG_G7]); + st->cr(); st->cr();
--- a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -140,3 +140,6 @@ *fr_addr = ret_frame; return true; } + +void JavaThread::cache_global_variables() { } +
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -719,6 +719,11 @@ ucontext_t *uc = (ucontext_t*)context; st->print_cr("Registers:"); + + // this is horrendously verbose but the layout of the registers in the + // context does not match how we defined our abstract Register set, so + // we can't just iterate through the gregs area + #ifdef AMD64 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); @@ -742,6 +747,63 @@ st->cr(); st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]); st->print(", RFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RFL]); + + st->cr(); + st->cr(); + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is only for the "general purpose" registers + + st->print_cr("RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); + print_location(st, uc->uc_mcontext.gregs[REG_RAX]); + st->cr(); + st->print_cr("RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); + print_location(st, uc->uc_mcontext.gregs[REG_RBX]); + st->cr(); + st->print_cr("RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); + print_location(st, uc->uc_mcontext.gregs[REG_RCX]); + st->cr(); + st->print_cr("RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]); + print_location(st, uc->uc_mcontext.gregs[REG_RDX]); + st->cr(); + st->print_cr("RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]); + print_location(st, uc->uc_mcontext.gregs[REG_RSP]); + st->cr(); + st->print_cr("RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]); + print_location(st, uc->uc_mcontext.gregs[REG_RSP]); + st->cr(); + st->print_cr("RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]); + print_location(st, uc->uc_mcontext.gregs[REG_RSI]); + st->cr(); + st->print_cr("RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]); + print_location(st, uc->uc_mcontext.gregs[REG_RDI]); + st->cr(); + st->print_cr("R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); + print_location(st, uc->uc_mcontext.gregs[REG_R8]); + st->cr(); + st->print_cr("R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]); + print_location(st, uc->uc_mcontext.gregs[REG_R9]); + st->cr(); + st->print_cr("R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]); + print_location(st, uc->uc_mcontext.gregs[REG_R10]); + st->cr(); + st->print_cr("R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]); + print_location(st, uc->uc_mcontext.gregs[REG_R11]); + st->cr(); + st->print_cr("R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); + print_location(st, uc->uc_mcontext.gregs[REG_R12]); + st->cr(); + st->print_cr("R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]); + print_location(st, uc->uc_mcontext.gregs[REG_R13]); + st->cr(); + st->print_cr("R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]); + print_location(st, uc->uc_mcontext.gregs[REG_R14]); + st->cr(); + st->print_cr("R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]); + print_location(st, uc->uc_mcontext.gregs[REG_R15]); + #else st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]); st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]); @@ -755,6 +817,39 @@ st->cr(); st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EIP]); st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EFL]); + + st->cr(); + st->cr(); + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is only for the "general purpose" registers + + st->print_cr("EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]); + print_location(st, uc->uc_mcontext.gregs[EAX]); + st->cr(); + st->print_cr("EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]); + print_location(st, uc->uc_mcontext.gregs[EBX]); + st->cr(); + st->print_cr("ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ECX]); + print_location(st, uc->uc_mcontext.gregs[ECX]); + st->cr(); + st->print_cr("EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDX]); + print_location(st, uc->uc_mcontext.gregs[EDX]); + st->cr(); + st->print_cr("ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[UESP]); + print_location(st, uc->uc_mcontext.gregs[UESP]); + st->cr(); + st->print_cr("EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBP]); + print_location(st, uc->uc_mcontext.gregs[EBP]); + st->cr(); + st->print_cr("ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ESI]); + print_location(st, uc->uc_mcontext.gregs[ESI]); + st->cr(); + st->print_cr("EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDI]); + print_location(st, uc->uc_mcontext.gregs[EDI]); + #endif // AMD64 st->cr(); st->cr(); @@ -773,6 +868,7 @@ print_hex_dump(st, pc - 16, pc + 16, sizeof(char)); } + #ifdef AMD64 void os::Solaris::init_thread_fpu_state(void) { // Nothing to do
--- a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -82,3 +82,6 @@ return true; } + +void JavaThread::cache_global_variables() { } +
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -377,18 +377,84 @@ st->print_cr("Registers:"); #ifdef AMD64 - st->print( "EAX=" INTPTR_FORMAT, uc->Rax); - st->print(", EBX=" INTPTR_FORMAT, uc->Rbx); - st->print(", ECX=" INTPTR_FORMAT, uc->Rcx); - st->print(", EDX=" INTPTR_FORMAT, uc->Rdx); + st->print( "RAX=" INTPTR_FORMAT, uc->Rax); + st->print(", RBX=" INTPTR_FORMAT, uc->Rbx); + st->print(", RCX=" INTPTR_FORMAT, uc->Rcx); + st->print(", RDX=" INTPTR_FORMAT, uc->Rdx); + st->cr(); + st->print( "RSP=" INTPTR_FORMAT, uc->Rsp); + st->print(", RBP=" INTPTR_FORMAT, uc->Rbp); + st->print(", RSI=" INTPTR_FORMAT, uc->Rsi); + st->print(", RDI=" INTPTR_FORMAT, uc->Rdi); + st->cr(); + st->print( "R8=" INTPTR_FORMAT, uc->R8); + st->print(", R9=" INTPTR_FORMAT, uc->R9); + st->print(", R10=" INTPTR_FORMAT, uc->R10); + st->print(", R11=" INTPTR_FORMAT, uc->R11); + st->cr(); + st->print( "R12=" INTPTR_FORMAT, uc->R12); + st->print(", R13=" INTPTR_FORMAT, uc->R13); + st->print(", R14=" INTPTR_FORMAT, uc->R14); + st->print(", R15=" INTPTR_FORMAT, uc->R15); + st->cr(); + st->print( "RIP=" INTPTR_FORMAT, uc->Rip); + st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags); + + st->cr(); + st->cr(); + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is only for the "general purpose" registers + + st->print_cr("RAX=" INTPTR_FORMAT, uc->Rax); + print_location(st, uc->Rax); + st->cr(); + st->print_cr("RBX=" INTPTR_FORMAT, uc->Rbx); + print_location(st, uc->Rbx); st->cr(); - st->print( "ESP=" INTPTR_FORMAT, uc->Rsp); - st->print(", EBP=" INTPTR_FORMAT, uc->Rbp); - st->print(", ESI=" INTPTR_FORMAT, uc->Rsi); - st->print(", EDI=" INTPTR_FORMAT, uc->Rdi); + st->print_cr("RCX=" INTPTR_FORMAT, uc->Rcx); + print_location(st, uc->Rcx); + st->cr(); + st->print_cr("RDX=" INTPTR_FORMAT, uc->Rdx); + print_location(st, uc->Rdx); + st->cr(); + st->print_cr("RSP=" INTPTR_FORMAT, uc->Rsp); + print_location(st, uc->Rsp); + st->cr(); + st->print_cr("RBP=" INTPTR_FORMAT, uc->Rbp); + print_location(st, uc->Rbp); + st->cr(); + st->print_cr("RSI=" INTPTR_FORMAT, uc->Rsi); + print_location(st, uc->Rsi); + st->cr(); + st->print_cr("RDI=" INTPTR_FORMAT, uc->Rdi); + print_location(st, uc->Rdi); + st->cr(); + st->print_cr("R8 =" INTPTR_FORMAT, uc->R8); + print_location(st, uc->R8); st->cr(); - st->print( "EIP=" INTPTR_FORMAT, uc->Rip); - st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags); + st->print_cr("R9 =" INTPTR_FORMAT, uc->R9); + print_location(st, uc->R9); + st->cr(); + st->print_cr("R10=" INTPTR_FORMAT, uc->R10); + print_location(st, uc->R10); + st->cr(); + st->print_cr("R11=" INTPTR_FORMAT, uc->R11); + print_location(st, uc->R11); + st->cr(); + st->print_cr("R12=" INTPTR_FORMAT, uc->R12); + print_location(st, uc->R12); + st->cr(); + st->print_cr("R13=" INTPTR_FORMAT, uc->R13); + print_location(st, uc->R13); + st->cr(); + st->print_cr("R14=" INTPTR_FORMAT, uc->R14); + print_location(st, uc->R14); + st->cr(); + st->print_cr("R15=" INTPTR_FORMAT, uc->R15); + print_location(st, uc->R15); #else st->print( "EAX=" INTPTR_FORMAT, uc->Eax); st->print(", EBX=" INTPTR_FORMAT, uc->Ebx); @@ -402,6 +468,38 @@ st->cr(); st->print( "EIP=" INTPTR_FORMAT, uc->Eip); st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags); + + st->cr(); + st->cr(); + + st->print_cr("Register to memory mapping:"); + st->cr(); + + // this is only for the "general purpose" registers + + st->print_cr("EAX=" INTPTR_FORMAT, uc->Eax); + print_location(st, uc->Eax); + st->cr(); + st->print_cr("EBX=" INTPTR_FORMAT, uc->Ebx); + print_location(st, uc->Ebx); + st->cr(); + st->print_cr("ECX=" INTPTR_FORMAT, uc->Ecx); + print_location(st, uc->Ecx); + st->cr(); + st->print_cr("EDX=" INTPTR_FORMAT, uc->Edx); + print_location(st, uc->Edx); + st->cr(); + st->print_cr("ESP=" INTPTR_FORMAT, uc->Esp); + print_location(st, uc->Esp); + st->cr(); + st->print_cr("EBP=" INTPTR_FORMAT, uc->Ebp); + print_location(st, uc->Ebp); + st->cr(); + st->print_cr("ESI=" INTPTR_FORMAT, uc->Esi); + print_location(st, uc->Esi); + st->cr(); + st->print_cr("EDI=" INTPTR_FORMAT, uc->Edi); + print_location(st, uc->Edi); #endif // AMD64 st->cr(); st->cr();
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -84,3 +84,6 @@ // nothing else to try return false; } + +void JavaThread::cache_global_variables() { } +
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -128,7 +128,11 @@ delete _overflow_arena; #ifdef ASSERT + // Save allocation type to execute assert in ~ResourceObj() + // which is called after this destructor. + ResourceObj::allocation_type at = _default_oop_recorder.get_allocation_type(); Copy::fill_to_bytes(this, sizeof(*this), badResourceValue); + ResourceObj::set_allocation_type((address)(&_default_oop_recorder), at); #endif }
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/asm/codeBuffer.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -102,7 +102,7 @@ _locs_point = NULL; _locs_own = false; _frozen = false; - debug_only(_index = -1); + debug_only(_index = (char)-1); debug_only(_outer = (CodeBuffer*)badAddress); } @@ -278,7 +278,7 @@ // special case during expansion which is handled internally. This // is done to guarantee proper cleanup of resources. void* operator new(size_t size) { return ResourceObj::operator new(size); } - void operator delete(void* p) { ResourceObj::operator delete(p); } + void operator delete(void* p) { ShouldNotCallThis(); } public: typedef int csize_t; // code size type; would be size_t except for history
--- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -448,6 +448,10 @@ _obj(obj), _info(info), _stub(stub) { } + void set_obj(LIR_Opr obj) { + _obj = obj; + } + virtual void emit_code(LIR_Assembler* e); virtual CodeEmitInfo* info() const { return _info; } virtual bool is_exception_throw_stub() const { return true; }
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -220,11 +220,13 @@ code_offsets->set_value(CodeOffsets::Deopt, assembler->emit_deopt_handler()); CHECK_BAILOUT(); - // Generate code for MethodHandle deopt handler. We can use the - // same code as for the normal deopt handler, we just need a - // different entry point address. - code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler()); - CHECK_BAILOUT(); + // Emit the MethodHandle deopt handler code (if required). + if (has_method_handle_invokes()) { + // We can use the same code as for the normal deopt handler, we + // just need a different entry point address. + code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler()); + CHECK_BAILOUT(); + } // Emit the handler to remove the activation from the stack and // dispatch to the caller. @@ -446,6 +448,7 @@ , _has_exception_handlers(false) , _has_fpu_code(true) // pessimistic assumption , _has_unsafe_access(false) +, _has_method_handle_invokes(false) , _bailout_msg(NULL) , _exception_info_list(NULL) , _allocator(NULL)
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -69,6 +69,7 @@ bool _has_exception_handlers; bool _has_fpu_code; bool _has_unsafe_access; + bool _has_method_handle_invokes; // True if this method has MethodHandle invokes. const char* _bailout_msg; ExceptionInfoList* _exception_info_list; ExceptionHandlerTable _exception_handler_table; @@ -147,6 +148,10 @@ // Statistics gathering void notice_inlined_method(ciMethod* method); + // JSR 292 + bool has_method_handle_invokes() const { return _has_method_handle_invokes; } + void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } + DebugInformationRecorder* debug_info_recorder() const; // = _env->debug_info(); Dependencies* dependency_recorder() const; // = _env->dependencies() ImplicitExceptionTable* implicit_exception_table() { return &_implicit_exception_table; } @@ -168,10 +173,19 @@ const char* bailout_msg() const { return _bailout_msg; } static int desired_max_code_buffer_size() { +#ifndef PPC return (int) NMethodSizeLimit; // default 256K or 512K +#else + // conditional branches on PPC are restricted to 16 bit signed + return MAX2((unsigned int)NMethodSizeLimit,32*K); +#endif } static int desired_max_constant_size() { +#ifndef PPC return (int) NMethodSizeLimit / 10; // about 25K +#else + return (MAX2((unsigned int)NMethodSizeLimit, 32*K)) / 10; +#endif } static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
--- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -90,7 +90,7 @@ if (outgoing) { // update the space reserved for arguments. - update_reserved_argument_area_size(out_preserve); + update_reserved_argument_area_size(out_preserve * BytesPerWord); } return new CallingConvention(args, out_preserve); } @@ -138,7 +138,7 @@ } assert(args->length() == signature->length(), "size mismatch"); out_preserve += SharedRuntime::out_preserve_stack_slots(); - update_reserved_argument_area_size(out_preserve); + update_reserved_argument_area_size(out_preserve * BytesPerWord); return new CallingConvention(args, out_preserve); }
--- a/hotspot/src/share/vm/c1/c1_FrameMap.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_FrameMap.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -154,7 +154,6 @@ static LIR_Opr method_handle_invoke_SP_save_opr(); static BasicTypeArray* signature_type_array_for(const ciMethod* method); - static BasicTypeArray* signature_type_array_for(const char * signature); // for outgoing calls, these also update the reserved area to // include space for arguments and any ABI area.
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -50,8 +50,7 @@ #endif // X86 - -#ifdef SPARC +#if defined(SPARC) || defined(PPC) FloatRegister LIR_OprDesc::as_float_reg() const { return FrameMap::nr2floatreg(fpu_regnr()); @@ -63,6 +62,19 @@ #endif +#ifdef ARM + +FloatRegister LIR_OprDesc::as_float_reg() const { + return as_FloatRegister(fpu_regnr()); +} + +FloatRegister LIR_OprDesc::as_double_reg() const { + return as_FloatRegister(fpu_regnrLo()); +} + +#endif + + LIR_Opr LIR_OprFact::illegalOpr = LIR_OprFact::illegal(); LIR_Opr LIR_OprFact::value_type(ValueType* type) { @@ -119,10 +131,14 @@ #ifndef PRODUCT void LIR_Address::verify() const { -#ifdef SPARC - assert(scale() == times_1, "Scaled addressing mode not available on SPARC and should not be used"); +#if defined(SPARC) || defined(PPC) + assert(scale() == times_1, "Scaled addressing mode not available on SPARC/PPC and should not be used"); assert(disp() == 0 || index()->is_illegal(), "can't have both"); #endif +#ifdef ARM + assert(disp() == 0 || index()->is_illegal(), "can't have both"); + assert(-4096 < disp() && disp() < 4096, "architecture constraint"); +#endif #ifdef _LP64 assert(base()->is_cpu_register(), "wrong base operand"); assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand"); @@ -173,13 +189,22 @@ if (!is_pointer() && !is_illegal()) { switch (as_BasicType(type_field())) { case T_LONG: - assert((kind_field() == cpu_register || kind_field() == stack_value) && size_field() == double_size, "must match"); + assert((kind_field() == cpu_register || kind_field() == stack_value) && + size_field() == double_size, "must match"); break; case T_FLOAT: - assert((kind_field() == fpu_register || kind_field() == stack_value) && size_field() == single_size, "must match"); + // FP return values can be also in CPU registers on ARM and PPC (softfp ABI) + assert((kind_field() == fpu_register || kind_field() == stack_value + ARM_ONLY(|| kind_field() == cpu_register) + PPC_ONLY(|| kind_field() == cpu_register) ) && + size_field() == single_size, "must match"); break; case T_DOUBLE: - assert((kind_field() == fpu_register || kind_field() == stack_value) && size_field() == double_size, "must match"); + // FP return values can be also in CPU registers on ARM and PPC (softfp ABI) + assert((kind_field() == fpu_register || kind_field() == stack_value + ARM_ONLY(|| kind_field() == cpu_register) + PPC_ONLY(|| kind_field() == cpu_register) ) && + size_field() == double_size, "must match"); break; case T_BOOLEAN: case T_CHAR: @@ -188,7 +213,8 @@ case T_INT: case T_OBJECT: case T_ARRAY: - assert((kind_field() == cpu_register || kind_field() == stack_value) && size_field() == single_size, "must match"); + assert((kind_field() == cpu_register || kind_field() == stack_value) && + size_field() == single_size, "must match"); break; case T_ILLEGAL: @@ -503,6 +529,10 @@ assert(opConvert->_info == NULL, "must be"); if (opConvert->_opr->is_valid()) do_input(opConvert->_opr); if (opConvert->_result->is_valid()) do_output(opConvert->_result); +#ifdef PPC + if (opConvert->_tmp1->is_valid()) do_temp(opConvert->_tmp1); + if (opConvert->_tmp2->is_valid()) do_temp(opConvert->_tmp2); +#endif do_stub(opConvert->_stub); break; @@ -530,7 +560,9 @@ LIR_OpAllocObj* opAllocObj = (LIR_OpAllocObj*)op; if (opAllocObj->_info) do_info(opAllocObj->_info); - if (opAllocObj->_opr->is_valid()) do_input(opAllocObj->_opr); + if (opAllocObj->_opr->is_valid()) { do_input(opAllocObj->_opr); + do_temp(opAllocObj->_opr); + } if (opAllocObj->_tmp1->is_valid()) do_temp(opAllocObj->_tmp1); if (opAllocObj->_tmp2->is_valid()) do_temp(opAllocObj->_tmp2); if (opAllocObj->_tmp3->is_valid()) do_temp(opAllocObj->_tmp3); @@ -826,10 +858,16 @@ assert(op->as_OpCompareAndSwap() != NULL, "must be"); LIR_OpCompareAndSwap* opCompareAndSwap = (LIR_OpCompareAndSwap*)op; + assert(opCompareAndSwap->_addr->is_valid(), "used"); + assert(opCompareAndSwap->_cmp_value->is_valid(), "used"); + assert(opCompareAndSwap->_new_value->is_valid(), "used"); if (opCompareAndSwap->_info) do_info(opCompareAndSwap->_info); - if (opCompareAndSwap->_addr->is_valid()) do_input(opCompareAndSwap->_addr); - if (opCompareAndSwap->_cmp_value->is_valid()) do_input(opCompareAndSwap->_cmp_value); - if (opCompareAndSwap->_new_value->is_valid()) do_input(opCompareAndSwap->_new_value); + do_input(opCompareAndSwap->_addr); + do_temp(opCompareAndSwap->_addr); + do_input(opCompareAndSwap->_cmp_value); + do_temp(opCompareAndSwap->_cmp_value); + do_input(opCompareAndSwap->_new_value); + do_temp(opCompareAndSwap->_new_value); if (opCompareAndSwap->_tmp1->is_valid()) do_temp(opCompareAndSwap->_tmp1); if (opCompareAndSwap->_tmp2->is_valid()) do_temp(opCompareAndSwap->_tmp2); if (opCompareAndSwap->_result->is_valid()) do_output(opCompareAndSwap->_result); @@ -1303,13 +1341,13 @@ info)); } -void LIR_List::unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, CodeStub* stub) { +void LIR_List::unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub) { append(new LIR_OpLock( lir_unlock, hdr, obj, lock, - LIR_OprFact::illegalOpr, + scratch, stub, NULL)); } @@ -1342,22 +1380,19 @@ } -void LIR_List::cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2) { - // Compare and swap produces condition code "zero" if contents_of(addr) == cmp_value, - // implying successful swap of new_value into addr - append(new LIR_OpCompareAndSwap(lir_cas_long, addr, cmp_value, new_value, t1, t2)); +void LIR_List::cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result) { + append(new LIR_OpCompareAndSwap(lir_cas_long, addr, cmp_value, new_value, t1, t2, result)); } -void LIR_List::cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2) { - // Compare and swap produces condition code "zero" if contents_of(addr) == cmp_value, - // implying successful swap of new_value into addr - append(new LIR_OpCompareAndSwap(lir_cas_obj, addr, cmp_value, new_value, t1, t2)); +void LIR_List::cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result) { + append(new LIR_OpCompareAndSwap(lir_cas_obj, addr, cmp_value, new_value, t1, t2, result)); } -void LIR_List::cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2) { - // Compare and swap produces condition code "zero" if contents_of(addr) == cmp_value, - // implying successful swap of new_value into addr - append(new LIR_OpCompareAndSwap(lir_cas_int, addr, cmp_value, new_value, t1, t2)); +void LIR_List::cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result) { + append(new LIR_OpCompareAndSwap(lir_cas_int, addr, cmp_value, new_value, t1, t2, result)); } @@ -1400,6 +1435,11 @@ out->print("fpu%d", fpu_regnr()); } else if (is_double_fpu()) { out->print("fpu%d", fpu_regnrLo()); +#elif defined(ARM) + } else if (is_single_fpu()) { + out->print("s%d", fpu_regnr()); + } else if (is_double_fpu()) { + out->print("d%d", fpu_regnrLo() >> 1); #else } else if (is_single_fpu()) { out->print(as_float_reg()->name()); @@ -1756,6 +1796,12 @@ print_bytecode(out, bytecode()); in_opr()->print(out); out->print(" "); result_opr()->print(out); out->print(" "); +#ifdef PPC + if(tmp1()->is_valid()) { + tmp1()->print(out); out->print(" "); + tmp2()->print(out); out->print(" "); + } +#endif } void LIR_OpConvert::print_bytecode(outputStream* out, Bytecodes::Code code) {
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -432,8 +432,7 @@ // for compatibility with RInfo int fpu () const { return lo_reg_half(); } #endif // X86 - -#ifdef SPARC +#if defined(SPARC) || defined(ARM) || defined(PPC) FloatRegister as_float_reg () const; FloatRegister as_double_reg () const; #endif @@ -519,14 +518,14 @@ , _type(type) , _disp(0) { verify(); } -#ifdef X86 +#if defined(X86) || defined(ARM) LIR_Address(LIR_Opr base, LIR_Opr index, Scale scale, intx disp, BasicType type): _base(base) , _index(index) , _scale(scale) , _type(type) , _disp(disp) { verify(); } -#endif // X86 +#endif // X86 || ARM LIR_Opr base() const { return _base; } LIR_Opr index() const { return _index; } @@ -566,7 +565,11 @@ LIR_OprDesc::float_type | LIR_OprDesc::fpu_register | LIR_OprDesc::single_size); } - +#if defined(ARM) + static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size); } + static LIR_Opr single_softfp(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::float_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); } + static LIR_Opr double_softfp(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::cpu_register | LIR_OprDesc::double_size); } +#endif #ifdef SPARC static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | @@ -593,7 +596,22 @@ LIR_OprDesc::double_size | LIR_OprDesc::is_xmm_mask); } #endif // X86 - +#ifdef PPC + static LIR_Opr double_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) | + (reg << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::fpu_register | + LIR_OprDesc::double_size); } + static LIR_Opr single_softfp(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::single_size); } + static LIR_Opr double_softfp(int reg1, int reg2) { return (LIR_Opr)((reg2 << LIR_OprDesc::reg1_shift) | + (reg1 << LIR_OprDesc::reg2_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::double_size); } +#endif // PPC static LIR_Opr virtual_register(int index, BasicType type) { LIR_Opr res; @@ -623,6 +641,22 @@ LIR_OprDesc::virtual_mask); break; +#ifdef __SOFTFP__ + case T_FLOAT: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::float_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::single_size | + LIR_OprDesc::virtual_mask); + break; + case T_DOUBLE: + res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + LIR_OprDesc::double_type | + LIR_OprDesc::cpu_register | + LIR_OprDesc::double_size | + LIR_OprDesc::virtual_mask); + break; +#else // __SOFTFP__ case T_FLOAT: res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | LIR_OprDesc::float_type | @@ -638,7 +672,7 @@ LIR_OprDesc::double_size | LIR_OprDesc::virtual_mask); break; - +#endif // __SOFTFP__ default: ShouldNotReachHere(); res = illegalOpr; } @@ -650,11 +684,18 @@ // old-style calculation; check if old and new method are equal LIR_OprDesc::OprType t = as_OprType(type); +#ifdef __SOFTFP__ + LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | + t | + LIR_OprDesc::cpu_register | + LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask); +#else // __SOFTFP__ LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | t | ((type == T_FLOAT || type == T_DOUBLE) ? LIR_OprDesc::fpu_register : LIR_OprDesc::cpu_register) | LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask); assert(res == old_res, "old and new method not equal"); -#endif +#endif // __SOFTFP__ +#endif // ASSERT return res; } @@ -1306,15 +1347,37 @@ private: Bytecodes::Code _bytecode; ConversionStub* _stub; +#ifdef PPC + LIR_Opr _tmp1; + LIR_Opr _tmp2; +#endif public: LIR_OpConvert(Bytecodes::Code code, LIR_Opr opr, LIR_Opr result, ConversionStub* stub) : LIR_Op1(lir_convert, opr, result) , _stub(stub) +#ifdef PPC + , _tmp1(LIR_OprDesc::illegalOpr()) + , _tmp2(LIR_OprDesc::illegalOpr()) +#endif , _bytecode(code) {} +#ifdef PPC + LIR_OpConvert(Bytecodes::Code code, LIR_Opr opr, LIR_Opr result, ConversionStub* stub + ,LIR_Opr tmp1, LIR_Opr tmp2) + : LIR_Op1(lir_convert, opr, result) + , _stub(stub) + , _tmp1(tmp1) + , _tmp2(tmp2) + , _bytecode(code) {} +#endif + Bytecodes::Code bytecode() const { return _bytecode; } ConversionStub* stub() const { return _stub; } +#ifdef PPC + LIR_Opr tmp1() const { return _tmp1; } + LIR_Opr tmp2() const { return _tmp2; } +#endif virtual void emit_code(LIR_Assembler* masm); virtual LIR_OpConvert* as_OpConvert() { return this; } @@ -1502,6 +1565,9 @@ LIR_Condition condition() const { assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); return _condition; } + void set_condition(LIR_Condition condition) { + assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); _condition = condition; + } void set_fpu_stack_size(int size) { _fpu_stack_size = size; } int fpu_stack_size() const { return _fpu_stack_size; } @@ -1650,8 +1716,9 @@ LIR_Opr _tmp2; public: - LIR_OpCompareAndSwap(LIR_Code code, LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2) - : LIR_Op(code, LIR_OprFact::illegalOpr, NULL) // no result, no info + LIR_OpCompareAndSwap(LIR_Code code, LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result) + : LIR_Op(code, result, NULL) // no result, no info , _addr(addr) , _cmp_value(cmp_value) , _new_value(new_value) @@ -1832,6 +1899,9 @@ void safepoint(LIR_Opr tmp, CodeEmitInfo* info) { append(new LIR_Op1(lir_safepoint, tmp, info)); } +#ifdef PPC + void convert(Bytecodes::Code code, LIR_Opr left, LIR_Opr dst, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_OpConvert(code, left, dst, NULL, tmp1, tmp2)); } +#endif void convert(Bytecodes::Code code, LIR_Opr left, LIR_Opr dst, ConversionStub* stub = NULL/*, bool is_32bit = false*/) { append(new LIR_OpConvert(code, left, dst, stub)); } void logical_and (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_and, left, right, dst)); } @@ -1867,9 +1937,12 @@ append(new LIR_Op2(lir_cmove, condition, src1, src2, dst)); } - void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2); - void cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2); - void cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2); + void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr); + void cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr); + void cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, + LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr); void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_abs , from, tmp, to)); } void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_sqrt, from, tmp, to)); } @@ -1950,7 +2023,7 @@ } void load_stack_address_monitor(int monitor_ix, LIR_Opr dst) { append(new LIR_Op1(lir_monaddr, LIR_OprFact::intConst(monitor_ix), dst)); } - void unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, CodeStub* stub); + void unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub); void lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info); void set_24bit_fpu() { append(new LIR_Op0(lir_24bit_FPU )); }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -438,6 +438,12 @@ default: ShouldNotReachHere(); } + // JSR 292 + // Record if this method has MethodHandle invokes. + if (op->is_method_handle_invoke()) { + compilation()->set_has_method_handle_invokes(true); + } + #if defined(X86) && defined(TIERED) // C2 leave fpu stack dirty clean it if (UseSSE < 2) {
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -31,6 +31,12 @@ #define __ gen()->lir()-> #endif +// TODO: ARM - Use some recognizable constant which still fits architectural constraints +#ifdef ARM +#define PATCHED_ADDR (204) +#else +#define PATCHED_ADDR (max_jint) +#endif void PhiResolverState::reset(int max_vregs) { // Initialize array sizes @@ -225,13 +231,13 @@ void LIRItem::load_item_force(LIR_Opr reg) { LIR_Opr r = result(); if (r != reg) { +#if !defined(ARM) && !defined(E500V2) if (r->type() != reg->type()) { // moves between different types need an intervening spill slot - LIR_Opr tmp = _gen->force_to_spill(r, reg->type()); - __ move(tmp, reg); - } else { - __ move(r, reg); + r = _gen->force_to_spill(r, reg->type()); } +#endif + __ move(r, reg); _result = reg; } } @@ -628,14 +634,14 @@ } -void LIRGenerator::monitor_exit(LIR_Opr object, LIR_Opr lock, LIR_Opr new_hdr, int monitor_no) { +void LIRGenerator::monitor_exit(LIR_Opr object, LIR_Opr lock, LIR_Opr new_hdr, LIR_Opr scratch, int monitor_no) { if (!GenerateSynchronizationCode) return; // setup registers LIR_Opr hdr = lock; lock = new_hdr; CodeStub* slow_path = new MonitorExitStub(lock, UseFastLocking, monitor_no); __ load_stack_address_monitor(monitor_no, lock); - __ unlock_object(hdr, object, lock, slow_path); + __ unlock_object(hdr, object, lock, scratch, slow_path); } @@ -1400,6 +1406,25 @@ } assert(addr->is_register(), "must be a register at this point"); +#ifdef ARM + // TODO: ARM - move to platform-dependent code + LIR_Opr tmp = FrameMap::R14_opr; + if (VM_Version::supports_movw()) { + __ move((LIR_Opr)card_table_base, tmp); + } else { + __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp); + } + + CardTableModRefBS* ct = (CardTableModRefBS*)_bs; + LIR_Address *card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BYTE); + if(((int)ct->byte_map_base & 0xff) == 0) { + __ move(tmp, card_addr); + } else { + LIR_Opr tmp_zero = new_register(T_INT); + __ move(LIR_OprFact::intConst(0), tmp_zero); + __ move(tmp_zero, card_addr); + } +#else // ARM LIR_Opr tmp = new_pointer_register(); if (TwoOperandLIRForm) { __ move(addr, tmp); @@ -1415,6 +1440,7 @@ new LIR_Address(tmp, load_constant(card_table_base), T_BYTE)); } +#endif // ARM } @@ -1507,7 +1533,7 @@ // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. - address = new LIR_Address(object.result(), max_jint, field_type); + address = new LIR_Address(object.result(), PATCHED_ADDR, field_type); } else { address = generate_address(object.result(), x->offset(), field_type); } @@ -1584,7 +1610,7 @@ // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. - address = new LIR_Address(object.result(), max_jint, field_type); + address = new LIR_Address(object.result(), PATCHED_ADDR, field_type); } else { address = generate_address(object.result(), x->offset(), field_type); } @@ -1844,6 +1870,8 @@ } #endif addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type); +#elif defined(ARM) + addr = generate_address(base_op, index_op, log2_scale, 0, dst_type); #else if (index_op->is_illegal() || log2_scale == 0) { #ifdef _LP64 @@ -1916,6 +1944,7 @@ __ convert(Bytecodes::_i2l, idx.result(), index_op); } else { #endif + // TODO: ARM also allows embedded shift in the address __ move(idx.result(), index_op); #ifdef _LP64 } @@ -2204,7 +2233,10 @@ // Assign new location to Local instruction for this local Local* local = x->state()->local_at(java_index)->as_Local(); assert(local != NULL, "Locals for incoming arguments must have been created"); +#ifndef __SOFTFP__ + // The java calling convention passes double as long and float as int. assert(as_ValueType(t)->tag() == local->type()->tag(), "check"); +#endif // __SOFTFP__ local->set_operand(dest); _instruction_for_operand.at_put_grow(dest->vreg_number(), local, NULL); java_index += type2size[t];
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -314,7 +314,7 @@ void logic_op (Bytecodes::Code code, LIR_Opr dst_reg, LIR_Opr left, LIR_Opr right); void monitor_enter (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info); - void monitor_exit (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, int monitor_no); + void monitor_exit (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no); void new_instance (LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info); @@ -338,6 +338,9 @@ } LIR_Address* emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark); + // the helper for generate_address + void add_large_constant(LIR_Opr src, int c, LIR_Opr dest); + // machine preferences and characteristics bool can_inline_as_constant(Value i) const; bool can_inline_as_constant(LIR_Const* c) const; @@ -393,6 +396,10 @@ return l; } +#ifdef __SOFTFP__ + void do_soft_float_compare(If *x); +#endif // __SOFTFP__ + void init(); SwitchRangeArray* create_lookup_ranges(TableSwitch* x); @@ -444,6 +451,7 @@ static LIR_Opr remOutOpr(); static LIR_Opr shiftCountOpr(); LIR_Opr syncTempOpr(); + LIR_Opr atomicLockOpr(); // returns a register suitable for saving the thread in a // call_runtime_leaf if one is needed.
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -169,7 +169,11 @@ } bool LinearScan::is_virtual_cpu_interval(const Interval* i) { +#if defined(__SOFTFP__) || defined(E500V2) + return i->reg_num() >= LIR_OprDesc::vreg_base; +#else return i->reg_num() >= LIR_OprDesc::vreg_base && (i->type() != T_FLOAT && i->type() != T_DOUBLE); +#endif // __SOFTFP__ or E500V2 } bool LinearScan::is_precolored_fpu_interval(const Interval* i) { @@ -177,7 +181,11 @@ } bool LinearScan::is_virtual_fpu_interval(const Interval* i) { +#if defined(__SOFTFP__) || defined(E500V2) + return false; +#else return i->reg_num() >= LIR_OprDesc::vreg_base && (i->type() == T_FLOAT || i->type() == T_DOUBLE); +#endif // __SOFTFP__ or E500V2 } bool LinearScan::is_in_fpu_register(const Interval* i) { @@ -2010,12 +2018,18 @@ return LIR_OprFact::single_cpu_oop(assigned_reg); } +#ifdef __SOFTFP__ + case T_FLOAT: // fall through +#endif // __SOFTFP__ case T_INT: { assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register"); assert(interval->assigned_regHi() == any_reg, "must not have hi register"); return LIR_OprFact::single_cpu(assigned_reg); } +#ifdef __SOFTFP__ + case T_DOUBLE: // fall through +#endif // __SOFTFP__ case T_LONG: { int assigned_regHi = interval->assigned_regHi(); assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register"); @@ -2033,7 +2047,7 @@ #ifdef _LP64 return LIR_OprFact::double_cpu(assigned_reg, assigned_reg); #else -#ifdef SPARC +#if defined(SPARC) || defined(PPC) return LIR_OprFact::double_cpu(assigned_regHi, assigned_reg); #else return LIR_OprFact::double_cpu(assigned_reg, assigned_regHi); @@ -2041,6 +2055,7 @@ #endif // LP64 } +#ifndef __SOFTFP__ case T_FLOAT: { #ifdef X86 if (UseSSE >= 1) { @@ -2069,6 +2084,11 @@ assert(interval->assigned_regHi() >= pd_first_fpu_reg && interval->assigned_regHi() <= pd_last_fpu_reg, "no fpu register"); assert(assigned_reg % 2 == 0 && assigned_reg + 1 == interval->assigned_regHi(), "must be sequential and even"); LIR_Opr result = LIR_OprFact::double_fpu(interval->assigned_regHi() - pd_first_fpu_reg, assigned_reg - pd_first_fpu_reg); +#elif defined(ARM) + assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register"); + assert(interval->assigned_regHi() >= pd_first_fpu_reg && interval->assigned_regHi() <= pd_last_fpu_reg, "no fpu register"); + assert(assigned_reg % 2 == 0 && assigned_reg + 1 == interval->assigned_regHi(), "must be sequential and even"); + LIR_Opr result = LIR_OprFact::double_fpu(assigned_reg - pd_first_fpu_reg, interval->assigned_regHi() - pd_first_fpu_reg); #else assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register"); assert(interval->assigned_regHi() == any_reg, "must not have hi register (double fpu values are stored in one register on Intel)"); @@ -2076,6 +2096,7 @@ #endif return result; } +#endif // __SOFTFP__ default: { ShouldNotReachHere(); @@ -2638,6 +2659,12 @@ #ifdef SPARC assert(opr->fpu_regnrLo() == opr->fpu_regnrHi() + 1, "assumed in calculation (only fpu_regnrHi is used)"); #endif +#ifdef ARM + assert(opr->fpu_regnrHi() == opr->fpu_regnrLo() + 1, "assumed in calculation (only fpu_regnrLo is used)"); +#endif +#ifdef PPC + assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrHi is used)"); +#endif VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrHi()); #ifdef _LP64 @@ -6135,6 +6162,17 @@ assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch"); LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op; + LIR_Op2* prev_cmp = NULL; + + for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) { + prev_op = instructions->at(j); + if(prev_op->code() == lir_cmp) { + assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2"); + prev_cmp = (LIR_Op2*)prev_op; + assert(prev_branch->cond() == prev_cmp->condition(), "should be the same"); + } + } + assert(prev_cmp != NULL, "should have found comp instruction for branch"); if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) { TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id())); @@ -6142,6 +6180,7 @@ // eliminate a conditional branch to the immediate successor prev_branch->change_block(last_branch->block()); prev_branch->negate_cond(); + prev_cmp->set_condition(prev_branch->cond()); instructions->truncate(instructions->length() - 1); } }
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -144,7 +144,7 @@ #ifndef TIERED case counter_overflow_id: // Not generated outside the tiered world #endif -#ifdef SPARC +#if defined(SPARC) || defined(PPC) case handle_exception_nofpu_id: // Unused on sparc #endif break; @@ -240,7 +240,8 @@ #undef FUNCTION_CASE - return "<unknown function>"; + // Soft float adds more runtime names. + return pd_name_for_address(entry); } @@ -896,7 +897,10 @@ } else { // patch the instruction <move reg, klass> NativeMovConstReg* n_copy = nativeMovConstReg_at(copy_buff); - assert(n_copy->data() == 0, "illegal init value"); + + assert(n_copy->data() == 0 || + n_copy->data() == (int)Universe::non_oop_word(), + "illegal init value"); assert(load_klass() != NULL, "klass not set"); n_copy->set_data((intx) (load_klass())); @@ -904,7 +908,7 @@ Disassembler::decode(copy_buff, copy_buff + *byte_count, tty); } -#ifdef SPARC +#if defined(SPARC) || defined(PPC) // Update the oop location in the nmethod with the proper // oop. When the code was generated, a NULL was stuffed // in the oop table and that table needs to be update to @@ -934,6 +938,14 @@ if (do_patch) { // replace instructions // first replace the tail, then the call +#ifdef ARM + if(stub_id == Runtime1::load_klass_patching_id && !VM_Version::supports_movw()) { + copy_buff -= *byte_count; + NativeMovConstReg* n_copy2 = nativeMovConstReg_at(copy_buff); + n_copy2->set_data((intx) (load_klass()), instr_pc); + } +#endif + for (int i = NativeCall::instruction_size; i < *byte_count; i++) { address ptr = copy_buff + i; int a_byte = (*ptr) & 0xFF; @@ -961,6 +973,12 @@ relocInfo::change_reloc_info_for_address(&iter2, (address) instr_pc2, relocInfo::none, relocInfo::oop_type); #endif +#ifdef PPC + { address instr_pc2 = instr_pc + NativeMovConstReg::lo_offset; + RelocIterator iter2(nm, instr_pc2, instr_pc2 + 1); + relocInfo::change_reloc_info_for_address(&iter2, (address) instr_pc2, relocInfo::none, relocInfo::oop_type); + } +#endif } } else {
--- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -159,6 +159,9 @@ static const char* name_for (StubID id); static const char* name_for_address(address entry); + // platform might add runtime names. + static const char* pd_name_for_address(address entry); + // method tracing static void trace_block_entry(jint block_id);
--- a/hotspot/src/share/vm/ci/ciField.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciField.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -339,7 +339,7 @@ if (_type != NULL) _type->print_name(); else tty->print("(reference)"); tty->print(" is_constant=%s", bool_to_str(_is_constant)); - if (_is_constant) { + if (_is_constant && is_static()) { tty->print(" constant_value="); _constant_value.print(); }
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -403,8 +403,9 @@ instanceKlass* ik = get_instanceKlass(); int max_n_fields = ik->fields()->length()/instanceKlass::next_offset; + Arena* arena = curEnv->arena(); _non_static_fields = - new (curEnv->arena()) GrowableArray<ciField*>(max_n_fields); + new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); NonStaticFieldFiller filler(curEnv, _non_static_fields); ik->do_nonstatic_fields(&filler); }
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -55,10 +55,10 @@ _exception_handlers = NULL; _liveness = NULL; _method_blocks = NULL; -#ifdef COMPILER2 +#if defined(COMPILER2) || defined(SHARK) _flow = NULL; _bcea = NULL; -#endif // COMPILER2 +#endif // COMPILER2 || SHARK ciEnv *env = CURRENT_ENV; if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) { @@ -123,10 +123,10 @@ _can_be_statically_bound = false; _method_blocks = NULL; _method_data = NULL; -#ifdef COMPILER2 +#if defined(COMPILER2) || defined(SHARK) _flow = NULL; _bcea = NULL; -#endif // COMPILER2 +#endif // COMPILER2 || SHARK } @@ -229,6 +229,20 @@ } +#ifdef SHARK +// ------------------------------------------------------------------ +// ciMethod::itable_index +// +// Get the position of this method's entry in the itable, if any. +int ciMethod::itable_index() { + check_is_loaded(); + assert(holder()->is_linked(), "must be linked"); + VM_ENTRY_MARK; + return klassItable::compute_itable_index(get_methodOop()); +} +#endif // SHARK + + // ------------------------------------------------------------------ // ciMethod::native_entry // @@ -294,34 +308,34 @@ // ------------------------------------------------------------------ // ciMethod::get_flow_analysis ciTypeFlow* ciMethod::get_flow_analysis() { -#ifdef COMPILER2 +#if defined(COMPILER2) || defined(SHARK) if (_flow == NULL) { ciEnv* env = CURRENT_ENV; _flow = new (env->arena()) ciTypeFlow(env, this); _flow->do_flow(); } return _flow; -#else // COMPILER2 +#else // COMPILER2 || SHARK ShouldNotReachHere(); return NULL; -#endif // COMPILER2 +#endif // COMPILER2 || SHARK } // ------------------------------------------------------------------ // ciMethod::get_osr_flow_analysis ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) { -#ifdef COMPILER2 +#if defined(COMPILER2) || defined(SHARK) // OSR entry points are always place after a call bytecode of some sort assert(osr_bci >= 0, "must supply valid OSR entry point"); ciEnv* env = CURRENT_ENV; ciTypeFlow* flow = new (env->arena()) ciTypeFlow(env, this, osr_bci); flow->do_flow(); return flow; -#else // COMPILER2 +#else // COMPILER2 || SHARK ShouldNotReachHere(); return NULL; -#endif // COMPILER2 +#endif // COMPILER2 || SHARK } // ------------------------------------------------------------------
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciMethod.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -70,7 +70,7 @@ // Optional liveness analyzer. MethodLiveness* _liveness; -#ifdef COMPILER2 +#if defined(COMPILER2) || defined(SHARK) ciTypeFlow* _flow; BCEscapeAnalyzer* _bcea; #endif @@ -141,6 +141,9 @@ // Runtime information. int vtable_index(); +#ifdef SHARK + int itable_index(); +#endif // SHARK address native_entry(); address interpreter_entry();
--- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -252,7 +252,7 @@ _arena(arena), _num_blocks(0), _code_size(meth->code_size()) { int block_estimate = _code_size / 8; - _blocks = new(_arena) GrowableArray<ciBlock *>(block_estimate); + _blocks = new(_arena) GrowableArray<ciBlock *>(_arena, block_estimate, 0, NULL); int b2bsize = _code_size * sizeof(ciBlock **); _bci_to_block = (ciBlock **) arena->Amalloc(b2bsize); Copy::zero_to_words((HeapWord*) _bci_to_block, b2bsize / sizeof(HeapWord));
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -2591,7 +2591,7 @@ StateVector* temp_vector, JsrSet* temp_set) { int dft_len = 100; - GrowableArray<Block*> stk(arena(), dft_len, 0, NULL); + GrowableArray<Block*> stk(dft_len); ciBlock* dummy = _methodBlocks->make_dummy_block(); JsrSet* root_set = new JsrSet(NULL, 0);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -62,6 +62,7 @@ ClassFileStream cfs1 = *cfs0; ClassFileStream* cfs = &cfs1; #ifdef ASSERT + assert(cfs->allocated_on_stack(),"should be local"); u1* old_current = cfs0->current(); #endif
--- a/hotspot/src/share/vm/classfile/verificationType.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/classfile/verificationType.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -70,7 +70,9 @@ } else if (is_array() && from.is_array()) { VerificationType comp_this = get_component(CHECK_false); VerificationType comp_from = from.get_component(CHECK_false); - return comp_this.is_assignable_from(comp_from, context, CHECK_false); + if (!comp_this.is_bogus() && !comp_from.is_bogus()) { + return comp_this.is_assignable_from(comp_from, context, CHECK_false); + } } return false; } @@ -98,7 +100,7 @@ CHECK_(VerificationType::bogus_type())); return VerificationType::reference_type(component); default: - ShouldNotReachHere(); + // Met an invalid type signature, e.g. [X return VerificationType::bogus_type(); } }
--- a/hotspot/src/share/vm/classfile/verifier.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -1847,12 +1847,8 @@ if (type == VerificationType::uninitialized_this_type()) { // The method must be an <init> method of either this class, or one of its // superclasses - klassOop oop = current_class()(); - Klass* klass = oop->klass_part(); - while (klass != NULL && ref_class_type.name() != klass->name()) { - klass = klass->super()->klass_part(); - } - if (klass == NULL) { + if (ref_class_type.name() != current_class()->name() && + !name_in_supers(ref_class_type.name(), current_class())) { verify_error(bci, "Bad <init> method call"); return; }
--- a/hotspot/src/share/vm/code/codeBlob.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/code/codeBlob.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -564,72 +564,53 @@ ShouldNotReachHere(); } -#ifndef PRODUCT - -void CodeBlob::print() const { - tty->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", this); - tty->print_cr("Framesize: %d", _frame_size); +void CodeBlob::print_on(outputStream* st) const { + st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", this); + st->print_cr("Framesize: %d", _frame_size); } - void CodeBlob::print_value_on(outputStream* st) const { st->print_cr("[CodeBlob]"); } -#endif - void BufferBlob::verify() { // unimplemented } -#ifndef PRODUCT - -void BufferBlob::print() const { - CodeBlob::print(); - print_value_on(tty); +void BufferBlob::print_on(outputStream* st) const { + CodeBlob::print_on(st); + print_value_on(st); } - void BufferBlob::print_value_on(outputStream* st) const { st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", this, name()); } - -#endif - void RuntimeStub::verify() { // unimplemented } -#ifndef PRODUCT - -void RuntimeStub::print() const { - CodeBlob::print(); - tty->print("Runtime Stub (" INTPTR_FORMAT "): ", this); - tty->print_cr(name()); - Disassembler::decode((CodeBlob*)this); +void RuntimeStub::print_on(outputStream* st) const { + CodeBlob::print_on(st); + st->print("Runtime Stub (" INTPTR_FORMAT "): ", this); + st->print_cr(name()); + Disassembler::decode((CodeBlob*)this, st); } - void RuntimeStub::print_value_on(outputStream* st) const { st->print("RuntimeStub (" INTPTR_FORMAT "): ", this); st->print(name()); } -#endif - void SingletonBlob::verify() { // unimplemented } -#ifndef PRODUCT - -void SingletonBlob::print() const { - CodeBlob::print(); - tty->print_cr(name()); - Disassembler::decode((CodeBlob*)this); +void SingletonBlob::print_on(outputStream* st) const { + CodeBlob::print_on(st); + st->print_cr(name()); + Disassembler::decode((CodeBlob*)this, st); } - void SingletonBlob::print_value_on(outputStream* st) const { st->print_cr(name()); } @@ -637,5 +618,3 @@ void DeoptimizationBlob::print_value_on(outputStream* st) const { st->print_cr("Deoptimization (frame not available)"); } - -#endif // PRODUCT
--- a/hotspot/src/share/vm/code/codeBlob.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/code/codeBlob.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -163,8 +163,9 @@ // Debugging virtual void verify(); - virtual void print() const PRODUCT_RETURN; - virtual void print_value_on(outputStream* st) const PRODUCT_RETURN; + void print() const { print_on(tty); } + virtual void print_on(outputStream* st) const; + virtual void print_value_on(outputStream* st) const; // Print the comment associated with offset on stream, if there is one virtual void print_block_comment(outputStream* stream, address block_begin) { @@ -209,8 +210,8 @@ bool is_alive() const { return true; } void verify(); - void print() const PRODUCT_RETURN; - void print_value_on(outputStream* st) const PRODUCT_RETURN; + void print_on(outputStream* st) const; + void print_value_on(outputStream* st) const; }; @@ -292,8 +293,8 @@ bool is_alive() const { return true; } void verify(); - void print() const PRODUCT_RETURN; - void print_value_on(outputStream* st) const PRODUCT_RETURN; + void print_on(outputStream* st) const; + void print_value_on(outputStream* st) const; }; @@ -317,8 +318,8 @@ bool is_alive() const { return true; } void verify(); // does nothing - void print() const PRODUCT_RETURN; - void print_value_on(outputStream* st) const PRODUCT_RETURN; + void print_on(outputStream* st) const; + void print_value_on(outputStream* st) const; }; @@ -373,7 +374,7 @@ void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ } // Printing - void print_value_on(outputStream* st) const PRODUCT_RETURN; + void print_value_on(outputStream* st) const; address unpack() const { return instructions_begin() + _unpack_offset; } address unpack_with_exception() const { return instructions_begin() + _unpack_with_exception; }
--- a/hotspot/src/share/vm/code/nmethod.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -65,6 +65,11 @@ if (is_native_method()) return false; return compiler()->is_c2(); } +bool nmethod::is_compiled_by_shark() const { + if (is_native_method()) return false; + assert(compiler() != NULL, "must be"); + return compiler()->is_shark(); +} @@ -1353,6 +1358,10 @@ CodeCache::remove_saved_code(this); } +#ifdef SHARK + ((SharkCompiler *) compiler())->free_compiled_method(instructions_begin()); +#endif // SHARK + ((CodeBlob*)(this))->flush(); CodeCache::free(this); @@ -1769,6 +1778,7 @@ // Method that knows how to preserve outgoing arguments at call. This method must be // called with a frame corresponding to a Java invoke void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { +#ifndef SHARK if (!method()->is_native()) { SimpleScopeDesc ssd(this, fr.pc()); Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci()); @@ -1776,6 +1786,7 @@ symbolOop signature = call->signature(); fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f); } +#endif // !SHARK } @@ -2279,6 +2290,8 @@ tty->print("(c1) "); } else if (is_compiled_by_c2()) { tty->print("(c2) "); + } else if (is_compiled_by_shark()) { + tty->print("(shark) "); } else { tty->print("(nm) "); } @@ -2472,8 +2485,12 @@ if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); if (block_begin == deopt_handler_begin()) stream->print_cr("[Deopt Handler Code]"); - if (block_begin == deopt_mh_handler_begin()) stream->print_cr("[Deopt MH Handler Code]"); + + if (has_method_handle_invokes()) + if (block_begin == deopt_mh_handler_begin()) stream->print_cr("[Deopt MH Handler Code]"); + if (block_begin == consts_begin()) stream->print_cr("[Constants]"); + if (block_begin == entry_point()) { methodHandle m = method(); if (m.not_null()) {
--- a/hotspot/src/share/vm/code/nmethod.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -329,6 +329,7 @@ bool is_compiled_by_c1() const; bool is_compiled_by_c2() const; + bool is_compiled_by_shark() const; // boundaries for different parts address code_begin () const { return _entry_point; } @@ -606,6 +607,8 @@ void print_nul_chk_table() PRODUCT_RETURN; void print_nmethod(bool print_code); + // need to re-define this from CodeBlob else the overload hides it + virtual void print_on(outputStream* st) const { CodeBlob::print_on(st); } void print_on(outputStream* st, const char* title) const; // Logging
--- a/hotspot/src/share/vm/code/vtableStubs.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/code/vtableStubs.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -67,8 +67,8 @@ } -void VtableStub::print() { - tty->print("vtable stub (index = %d, receiver_location = %d, code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "[)", +void VtableStub::print_on(outputStream* st) const { + st->print("vtable stub (index = %d, receiver_location = %d, code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "[)", index(), receiver_location(), code_begin(), code_end()); }
--- a/hotspot/src/share/vm/code/vtableStubs.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/code/vtableStubs.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -86,7 +86,9 @@ bool is_abstract_method_error(address epc) { return epc == code_begin()+_ame_offset; } bool is_null_pointer_exception(address epc) { return epc == code_begin()+_npe_offset; } - void print(); + void print_on(outputStream* st) const; + void print() const { print_on(tty); } + };
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,18 +45,26 @@ // Missing feature tests virtual bool supports_native() { return true; } virtual bool supports_osr () { return true; } -#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2)) +#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)) virtual bool is_c1 () { return false; } virtual bool is_c2 () { return false; } + virtual bool is_shark() { return false; } #else #ifdef COMPILER1 bool is_c1 () { return true; } bool is_c2 () { return false; } + bool is_shark() { return false; } #endif // COMPILER1 #ifdef COMPILER2 bool is_c1 () { return false; } bool is_c2 () { return true; } + bool is_shark() { return false; } #endif // COMPILER2 +#ifdef SHARK + bool is_c1 () { return false; } + bool is_c2 () { return false; } + bool is_shark() { return true; } +#endif // SHARK #endif // TIERED // Customization
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -568,6 +568,14 @@ #endif #endif // COMPILER2 +#ifdef SHARK +#if defined(COMPILER1) || defined(COMPILER2) +#error "Can't use COMPILER1 or COMPILER2 with shark" +#endif + _compilers[0] = new SharkCompiler(); + _compilers[1] = _compilers[0]; +#endif + // Initialize the CompileTask free list _task_free_list = NULL;
--- a/hotspot/src/share/vm/compiler/disassembler.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/compiler/disassembler.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -371,7 +371,7 @@ address decode_env::decode_instructions(address start, address end) { _start = start; _end = end; - assert((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment() == 0), "misaligned insn addr"); + assert(((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment()) == 0), "misaligned insn addr"); const int show_bytes = false; // for disassembler debugging @@ -423,8 +423,14 @@ env.output()->print_cr("Decoding compiled method " INTPTR_FORMAT ":", nm); env.output()->print_cr("Code:"); +#ifdef SHARK + SharkEntry* entry = (SharkEntry *) nm->instructions_begin(); + unsigned char* p = entry->code_start(); + unsigned char* end = entry->code_limit(); +#else unsigned char* p = nm->instructions_begin(); unsigned char* end = nm->instructions_end(); +#endif // SHARK // If there has been profiling, print the buckets. if (FlatProfiler::bucket_start_for(p) != NULL) {
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -158,13 +158,18 @@ // The line below is the worst bit of C++ hackery I've ever written // (Detlefs, 11/23). You should think of it as equivalent to // "_regions(100, true)": initialize the growable array and inform it - // that it should allocate its elem array(s) on the C heap. The first - // argument, however, is actually a comma expression (new-expr, 100). - // The purpose of the new_expr is to inform the growable array that it - // is *already* allocated on the C heap: it uses the placement syntax to - // keep it from actually doing any allocation. - _markedRegions((ResourceObj::operator new (sizeof(GrowableArray<HeapRegion*>), - (void*)&_markedRegions, + // that it should allocate its elem array(s) on the C heap. + // + // The first argument, however, is actually a comma expression + // (set_allocation_type(this, C_HEAP), 100). The purpose of the + // set_allocation_type() call is to replace the default allocation + // type for embedded objects STACK_OR_EMBEDDED with C_HEAP. It will + // allow to pass the assert in GenericGrowableArray() which checks + // that a growable array object must be on C heap if elements are. + // + // Note: containing object is allocated on C heap since it is CHeapObj. + // + _markedRegions((ResourceObj::set_allocation_type((address)&_markedRegions, ResourceObj::C_HEAP), 100), true),
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -42,14 +42,19 @@ // The line below is the worst bit of C++ hackery I've ever written // (Detlefs, 11/23). You should think of it as equivalent to // "_regions(100, true)": initialize the growable array and inform it - // that it should allocate its elem array(s) on the C heap. The first - // argument, however, is actually a comma expression (new-expr, 100). - // The purpose of the new_expr is to inform the growable array that it - // is *already* allocated on the C heap: it uses the placement syntax to - // keep it from actually doing any allocation. - _regions((ResourceObj::operator new (sizeof(GrowableArray<HeapRegion*>), - (void*)&_regions, - ResourceObj::C_HEAP), + // that it should allocate its elem array(s) on the C heap. + // + // The first argument, however, is actually a comma expression + // (set_allocation_type(this, C_HEAP), 100). The purpose of the + // set_allocation_type() call is to replace the default allocation + // type for embedded objects STACK_OR_EMBEDDED with C_HEAP. It will + // allow to pass the assert in GenericGrowableArray() which checks + // that a growable array object must be on C heap if elements are. + // + // Note: containing object is allocated on C heap since it is CHeapObj. + // + _regions((ResourceObj::set_allocation_type((address)&_regions, + ResourceObj::C_HEAP), (int)max_size), true), _next_rr_candidate(0),
--- a/hotspot/src/share/vm/includeDB_compiler1 Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/includeDB_compiler1 Thu Sep 02 22:11:05 2010 -0700 @@ -252,6 +252,7 @@ c1_LIRGenerator.cpp ciInstance.hpp c1_LIRGenerator.cpp heapRegion.hpp c1_LIRGenerator.cpp sharedRuntime.hpp +c1_LIRGenerator.cpp stubRoutines.hpp c1_LIRGenerator.hpp c1_Instruction.hpp c1_LIRGenerator.hpp c1_LIR.hpp @@ -270,6 +271,8 @@ c1_LIRGenerator_<arch>.cpp ciTypeArrayKlass.hpp c1_LIRGenerator_<arch>.cpp sharedRuntime.hpp c1_LIRGenerator_<arch>.cpp vmreg_<arch>.inline.hpp +c1_LIRGenerator_<arch>.cpp stubRoutines.hpp + c1_LinearScan.cpp bitMap.inline.hpp c1_LinearScan.cpp c1_CFGPrinter.hpp @@ -413,6 +416,7 @@ compileBroker.cpp c1_Compiler.hpp frame_<arch>.cpp c1_Runtime1.hpp +frame_<arch>.cpp vframeArray.hpp globals.cpp c1_globals.hpp
--- a/hotspot/src/share/vm/includeDB_compiler2 Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/includeDB_compiler2 Thu Sep 02 22:11:05 2010 -0700 @@ -911,6 +911,7 @@ reg_split.cpp addnode.hpp reg_split.cpp allocation.inline.hpp reg_split.cpp callnode.hpp +reg_split.cpp c2compiler.hpp reg_split.cpp cfgnode.hpp reg_split.cpp chaitin.hpp reg_split.cpp loopnode.hpp
--- a/hotspot/src/share/vm/includeDB_core Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/includeDB_core Thu Sep 02 22:11:05 2010 -0700 @@ -284,6 +284,7 @@ atomic_<os_arch>.inline.hpp atomic.hpp atomic_<os_arch>.inline.hpp os.hpp atomic_<os_arch>.inline.hpp vm_version_<arch>.hpp +atomic_<os_arch>.inline.hpp orderAccess_<os_arch>.inline.hpp // attachListener is jck optional, put cpp deps in includeDB_features @@ -1734,6 +1735,7 @@ genCollectedHeap.cpp space.hpp genCollectedHeap.cpp symbolTable.hpp genCollectedHeap.cpp systemDictionary.hpp +genCollectedHeap.cpp vmError.hpp genCollectedHeap.cpp vmGCOperations.hpp genCollectedHeap.cpp vmSymbols.hpp genCollectedHeap.cpp vmThread.hpp @@ -3230,6 +3232,7 @@ os.cpp events.hpp os.cpp frame.inline.hpp os.cpp hpi.hpp +os.cpp icBuffer.hpp os.cpp interfaceSupport.hpp os.cpp interpreter.hpp os.cpp java.hpp @@ -3241,6 +3244,7 @@ os.cpp oop.inline.hpp os.cpp os.hpp os.cpp os_<os_family>.inline.hpp +os.cpp privilegedStack.hpp os.cpp stubRoutines.hpp os.cpp systemDictionary.hpp os.cpp threadService.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/includeDB_shark Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,371 @@ +// +// Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. +// Copyright 2008, 2009, 2010 Red Hat, Inc. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// +// + +// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! + +ciMethod.cpp ciTypeFlow.hpp +ciMethod.cpp methodOop.hpp + +ciTypeFlow.cpp allocation.inline.hpp +ciTypeFlow.cpp bytecode.hpp +ciTypeFlow.cpp bytecodes.hpp +ciTypeFlow.cpp ciConstant.hpp +ciTypeFlow.cpp ciField.hpp +ciTypeFlow.cpp ciMethod.hpp +ciTypeFlow.cpp ciMethodData.hpp +ciTypeFlow.cpp ciObjArrayKlass.hpp +ciTypeFlow.cpp ciStreams.hpp +ciTypeFlow.cpp ciTypeArrayKlass.hpp +ciTypeFlow.cpp ciTypeFlow.hpp +ciTypeFlow.cpp compileLog.hpp +ciTypeFlow.cpp deoptimization.hpp +ciTypeFlow.cpp growableArray.hpp +ciTypeFlow.cpp shark_globals.hpp + +ciTypeFlow.hpp ciEnv.hpp +ciTypeFlow.hpp ciKlass.hpp +ciTypeFlow.hpp ciMethodBlocks.hpp + +cppInterpreter_<arch>.cpp shark_globals.hpp + +compileBroker.cpp sharkCompiler.hpp + +disassembler.cpp sharkEntry.hpp + +globals.hpp shark_globals_<arch>.hpp + +globals.cpp shark_globals.hpp + +llvmValue.hpp llvmHeaders.hpp +llvmValue.hpp sharkContext.hpp +llvmValue.hpp sharkType.hpp + +nmethod.cpp sharkCompiler.hpp + +sharedRuntime_<arch>.cpp compileBroker.hpp +sharedRuntime_<arch>.cpp sharkCompiler.hpp + +shark_globals.cpp shark_globals.hpp + +shark_globals.hpp shark_globals_<arch>.hpp +shark_globals.hpp globals.hpp + +sharkBlock.cpp debug.hpp +sharkBlock.cpp bytecodes.hpp +sharkBlock.cpp llvmHeaders.hpp +sharkBlock.cpp llvmValue.hpp +sharkBlock.cpp shark_globals.hpp +sharkBlock.cpp sharkBlock.hpp +sharkBlock.cpp sharkBuilder.hpp +sharkBlock.cpp sharkConstant.hpp +sharkBlock.cpp sharkState.hpp +sharkBlock.cpp sharkValue.hpp + +sharkBlock.hpp allocation.hpp +sharkBlock.hpp ciMethod.hpp +sharkBlock.hpp ciStreams.hpp +sharkBlock.hpp debug.hpp +sharkBlock.hpp llvmHeaders.hpp +sharkBlock.hpp sharkBuilder.hpp +sharkBlock.hpp sharkConstant.hpp +sharkBlock.hpp sharkInvariants.hpp +sharkBlock.hpp sharkState.hpp +sharkBlock.hpp sharkValue.hpp + +sharkBuilder.cpp ciMethod.hpp +sharkBuilder.cpp debug.hpp +sharkBuilder.cpp llvmHeaders.hpp +sharkBuilder.cpp llvmValue.hpp +sharkBuilder.cpp methodOop.hpp +sharkBuilder.cpp os.hpp +sharkBuilder.cpp resourceArea.hpp +sharkBuilder.cpp llvmHeaders.hpp +sharkBuilder.cpp sharkBuilder.hpp +sharkBuilder.cpp sharkContext.hpp +sharkBuilder.cpp sharkRuntime.hpp +sharkBuilder.cpp synchronizer.hpp +sharkBuilder.cpp thread.hpp + +sharkBuilder.hpp barrierSet.hpp +sharkBuilder.hpp cardTableModRefBS.hpp +sharkBuilder.hpp ciType.hpp +sharkBuilder.hpp debug.hpp +sharkBuilder.hpp llvmHeaders.hpp +sharkBuilder.hpp llvmValue.hpp +sharkBuilder.hpp sizes.hpp +sharkBuilder.hpp sharkCodeBuffer.hpp +sharkBuilder.hpp sharkType.hpp +sharkBuilder.hpp sharkValue.hpp +sharkBuilder.hpp sharkEntry.hpp + +sharkCacheDecache.cpp ciMethod.hpp +sharkCacheDecache.cpp debugInfoRec.hpp +sharkCacheDecache.cpp llvmValue.hpp +sharkCacheDecache.cpp sharkBuilder.hpp +sharkCacheDecache.cpp sharkCacheDecache.hpp +sharkCacheDecache.cpp sharkFunction.hpp +sharkCacheDecache.cpp sharkState.hpp + +sharkCacheDecache.hpp ciMethod.hpp +sharkCacheDecache.hpp debugInfoRec.hpp +sharkCacheDecache.hpp sharkBuilder.hpp +sharkCacheDecache.hpp sharkFunction.hpp +sharkCacheDecache.hpp sharkStateScanner.hpp + +sharkCodeBuffer.hpp allocation.hpp +sharkCodeBuffer.hpp codeBuffer.hpp +sharkCodeBuffer.hpp llvmHeaders.hpp + +sharkCompiler.cpp abstractCompiler.hpp +sharkCompiler.cpp ciEnv.hpp +sharkCompiler.cpp ciMethod.hpp +sharkCompiler.cpp debug.hpp +sharkCompiler.cpp debugInfoRec.hpp +sharkCompiler.cpp dependencies.hpp +sharkCompiler.cpp exceptionHandlerTable.hpp +sharkCompiler.cpp llvmHeaders.hpp +sharkCompiler.cpp oopMap.hpp +sharkCompiler.cpp oopRecorder.hpp +sharkCompiler.cpp shark_globals.hpp +sharkCompiler.cpp sharkBuilder.hpp +sharkCompiler.cpp sharkCodeBuffer.hpp +sharkCompiler.cpp sharkCompiler.hpp +sharkCompiler.cpp sharkContext.hpp +sharkCompiler.cpp sharkEntry.hpp +sharkCompiler.cpp sharkFunction.hpp +sharkCompiler.cpp sharkMemoryManager.hpp +sharkCompiler.cpp sharkNativeWrapper.hpp + +sharkCompiler.hpp abstractCompiler.hpp +sharkCompiler.hpp ciEnv.hpp +sharkCompiler.hpp ciMethod.hpp +sharkCompiler.hpp compileBroker.hpp +sharkCompiler.hpp llvmHeaders.hpp +sharkCompiler.hpp sharkMemoryManager.hpp + +sharkContext.cpp arrayOop.hpp +sharkContext.cpp globalDefinitions.hpp +sharkContext.cpp llvmHeaders.hpp +sharkContext.cpp oop.hpp +sharkContext.cpp sharkContext.hpp + +sharkContext.hpp llvmHeaders.hpp +sharkContext.hpp sharkCompiler.hpp + +sharkConstant.cpp ciInstance.hpp +sharkConstant.cpp ciStreams.hpp +sharkConstant.cpp sharkBuilder.hpp +sharkConstant.cpp sharkConstant.hpp +sharkConstant.cpp sharkValue.hpp + +sharkConstant.hpp allocation.hpp +sharkConstant.hpp ciStreams.hpp +sharkConstant.hpp sharkBuilder.hpp +sharkConstant.hpp sharkValue.hpp + +sharkEntry.hpp llvmHeaders.hpp + +sharkFunction.cpp allocation.hpp +sharkFunction.cpp ciTypeFlow.hpp +sharkFunction.cpp debug.hpp +sharkFunction.cpp llvmHeaders.hpp +sharkFunction.cpp llvmValue.hpp +sharkFunction.cpp shark_globals.hpp +sharkFunction.cpp sharkBuilder.hpp +sharkFunction.cpp sharkEntry.hpp +sharkFunction.cpp sharkFunction.hpp +sharkFunction.cpp sharkState.hpp +sharkFunction.cpp sharkTopLevelBlock.hpp + +sharkFunction.hpp allocation.hpp +sharkFunction.hpp ciEnv.hpp +sharkFunction.hpp ciStreams.hpp +sharkFunction.hpp ciTypeFlow.hpp +sharkFunction.hpp llvmHeaders.hpp +sharkFunction.hpp llvmValue.hpp +sharkFunction.hpp sharkBuilder.hpp +sharkFunction.hpp sharkContext.hpp +sharkFunction.hpp sharkInvariants.hpp +sharkFunction.hpp sharkStack.hpp + +sharkInliner.cpp allocation.hpp +sharkInliner.cpp bytecodes.hpp +sharkInliner.cpp ciField.hpp +sharkInliner.cpp ciMethod.hpp +sharkInliner.cpp ciStreams.hpp +sharkInliner.cpp shark_globals.hpp +sharkInliner.cpp sharkBlock.hpp +sharkInliner.cpp sharkConstant.hpp +sharkInliner.cpp sharkInliner.hpp +sharkInliner.cpp sharkIntrinsics.hpp +sharkInliner.cpp sharkState.hpp +sharkInliner.cpp sharkValue.hpp + +sharkInliner.hpp allocation.hpp +sharkInliner.hpp ciMethod.hpp +sharkInliner.hpp llvmHeaders.hpp +sharkInliner.hpp sharkState.hpp + +sharkIntrinsics.cpp ciMethod.hpp +sharkIntrinsics.cpp llvmHeaders.hpp +sharkIntrinsics.cpp shark_globals.hpp +sharkIntrinsics.cpp sharkIntrinsics.hpp +sharkIntrinsics.cpp sharkState.hpp +sharkIntrinsics.cpp sharkValue.hpp + +sharkIntrinsics.hpp allocation.hpp +sharkIntrinsics.hpp ciMethod.hpp +sharkIntrinsics.hpp llvmHeaders.hpp +sharkIntrinsics.hpp sharkState.hpp + +sharkInvariants.cpp sharkInvariants.hpp + +sharkInvariants.hpp allocation.hpp +sharkInvariants.hpp ciEnv.hpp +sharkInvariants.hpp ciMethod.hpp +sharkInvariants.hpp ciInstanceKlass.hpp +sharkInvariants.hpp ciTypeFlow.hpp +sharkInvariants.hpp debugInfoRec.hpp +sharkInvariants.hpp dependencies.hpp +sharkInvariants.hpp llvmHeaders.hpp +sharkInvariants.hpp sharkBuilder.hpp + +sharkMemoryManager.hpp llvmHeaders.hpp +sharkMemoryManager.hpp sharkEntry.hpp + +sharkMemoryManager.cpp llvmHeaders.hpp +sharkMemoryManager.cpp sharkEntry.hpp +sharkMemoryManager.cpp sharkMemoryManager.hpp + +sharkNativeWrapper.cpp llvmHeaders.hpp +sharkNativeWrapper.cpp sharkNativeWrapper.hpp +sharkNativeWrapper.cpp sharkType.hpp + +sharkNativeWrapper.hpp handles.hpp +sharkNativeWrapper.hpp llvmHeaders.hpp +sharkNativeWrapper.hpp sharkBuilder.hpp +sharkNativeWrapper.hpp sharkContext.hpp +sharkNativeWrapper.hpp sharkInvariants.hpp +sharkNativeWrapper.hpp sharkStack.hpp + +sharkRuntime.cpp biasedLocking.hpp +sharkRuntime.cpp deoptimization.hpp +sharkRuntime.cpp llvmHeaders.hpp +sharkRuntime.cpp klassOop.hpp +sharkRuntime.cpp sharkRuntime.hpp +sharkRuntime.cpp stack_<arch>.inline.hpp +sharkRuntime.cpp thread.hpp + +sharkRuntime.hpp allocation.hpp +sharkRuntime.hpp llvmHeaders.hpp +sharkRuntime.hpp llvmValue.hpp +sharkRuntime.hpp klassOop.hpp +sharkRuntime.hpp thread.hpp + +sharkStack.cpp llvmHeaders.hpp +sharkStack.cpp sharkFunction.hpp +sharkStack.cpp sharkNativeWrapper.hpp +sharkStack.cpp sharkStack.hpp +sharkStack.cpp sharkType.hpp + +sharkStack.hpp llvmHeaders.hpp +sharkStack.hpp sharkInvariants.hpp +sharkStack.hpp sharkType.hpp + +sharkState.cpp allocation.hpp +sharkState.cpp ciType.hpp +sharkState.cpp ciTypeFlow.hpp +sharkState.cpp sharkBuilder.hpp +sharkState.cpp sharkCacheDecache.hpp +sharkState.cpp sharkState.hpp +sharkState.cpp sharkTopLevelBlock.hpp +sharkState.cpp sharkType.hpp +sharkState.cpp sharkValue.hpp + +sharkState.hpp allocation.hpp +sharkState.hpp ciMethod.hpp +sharkState.hpp llvmHeaders.hpp +sharkState.hpp sharkBuilder.hpp +sharkState.hpp sharkInvariants.hpp +sharkState.hpp sharkValue.hpp + +sharkStateScanner.cpp sharkState.hpp +sharkStateScanner.cpp sharkStateScanner.hpp + +sharkStateScanner.hpp allocation.hpp +sharkStateScanner.hpp llvmHeaders.hpp +sharkStateScanner.hpp sharkFunction.hpp +sharkStateScanner.hpp sharkInvariants.hpp + +sharkTopLevelBlock.cpp allocation.hpp +sharkTopLevelBlock.cpp bytecodes.hpp +sharkTopLevelBlock.cpp ciField.hpp +sharkTopLevelBlock.cpp ciInstance.hpp +sharkTopLevelBlock.cpp ciObjArrayKlass.hpp +sharkTopLevelBlock.cpp ciStreams.hpp +sharkTopLevelBlock.cpp ciType.hpp +sharkTopLevelBlock.cpp ciTypeFlow.hpp +sharkTopLevelBlock.cpp debug.hpp +sharkTopLevelBlock.cpp deoptimization.hpp +sharkTopLevelBlock.cpp llvmHeaders.hpp +sharkTopLevelBlock.cpp llvmValue.hpp +sharkTopLevelBlock.cpp shark_globals.hpp +sharkTopLevelBlock.cpp sharkCacheDecache.hpp +sharkTopLevelBlock.cpp sharkTopLevelBlock.hpp +sharkTopLevelBlock.cpp sharkBuilder.hpp +sharkTopLevelBlock.cpp sharkConstant.hpp +sharkTopLevelBlock.cpp sharkInliner.hpp +sharkTopLevelBlock.cpp sharkState.hpp +sharkTopLevelBlock.cpp sharkValue.hpp + +sharkTopLevelBlock.hpp allocation.hpp +sharkTopLevelBlock.hpp bytecodes.hpp +sharkTopLevelBlock.hpp ciStreams.hpp +sharkTopLevelBlock.hpp ciType.hpp +sharkTopLevelBlock.hpp ciTypeFlow.hpp +sharkTopLevelBlock.hpp llvmHeaders.hpp +sharkTopLevelBlock.hpp sharkBlock.hpp +sharkTopLevelBlock.hpp sharkBuilder.hpp +sharkTopLevelBlock.hpp sharkFunction.hpp +sharkTopLevelBlock.hpp sharkState.hpp +sharkTopLevelBlock.hpp sharkValue.hpp + +sharkType.hpp allocation.hpp +sharkType.hpp ciType.hpp +sharkType.hpp globalDefinitions.hpp +sharkType.hpp llvmHeaders.hpp +sharkType.hpp sharkContext.hpp + +sharkValue.cpp ciType.hpp +sharkValue.cpp llvmHeaders.hpp +sharkValue.cpp llvmValue.hpp +sharkValue.cpp sharkBuilder.hpp +sharkValue.cpp sharkValue.hpp + +sharkValue.hpp allocation.hpp +sharkValue.hpp ciType.hpp +sharkValue.hpp llvmHeaders.hpp +sharkValue.hpp llvmValue.hpp +sharkValue.hpp sharkType.hpp
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -339,7 +339,8 @@ #define CHECK_NULL(obj_) \ if ((obj_) == NULL) { \ VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), ""); \ - } + } \ + VERIFY_OOP(obj_) #define VMdoubleConstZero() 0.0 #define VMdoubleConstOne() 1.0 @@ -509,7 +510,7 @@ /* 0xB0 */ &&opc_areturn, &&opc_return, &&opc_getstatic, &&opc_putstatic, /* 0xB4 */ &&opc_getfield, &&opc_putfield, &&opc_invokevirtual,&&opc_invokespecial, -/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,NULL, &&opc_new, +/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,&&opc_default, &&opc_new, /* 0xBC */ &&opc_newarray, &&opc_anewarray, &&opc_arraylength, &&opc_athrow, /* 0xC0 */ &&opc_checkcast, &&opc_instanceof, &&opc_monitorenter, &&opc_monitorexit, @@ -539,6 +540,7 @@ // this will trigger a VERIFY_OOP on entry if (istate->msg() != initialize && ! METHOD->is_static()) { oop rcvr = LOCALS_OBJECT(0); + VERIFY_OOP(rcvr); } #endif // #define HACK @@ -547,7 +549,7 @@ #endif // HACK /* QQQ this should be a stack method so we don't know actual direction */ - assert(istate->msg() == initialize || + guarantee(istate->msg() == initialize || topOfStack >= istate->stack_limit() && topOfStack < istate->stack_base(), "Stack top out of range"); @@ -613,6 +615,7 @@ rcvr = METHOD->constants()->pool_holder()->klass_part()->java_mirror(); } else { rcvr = LOCALS_OBJECT(0); + VERIFY_OOP(rcvr); } // The initial monitor is ours for the taking BasicObjectLock* mon = &istate->monitor_base()[-1]; @@ -735,6 +738,7 @@ case popping_frame: { // returned from a java call to pop the frame, restart the call // clear the message so we don't confuse ourselves later + ShouldNotReachHere(); // we don't return this. assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); istate->set_msg(no_request); THREAD->clr_pop_frame_in_process(); @@ -801,6 +805,7 @@ // continue locking now that we have a monitor to use // we expect to find newly allocated monitor at the "top" of the monitor stack. oop lockee = STACK_OBJECT(-1); + VERIFY_OOP(lockee); // derefing's lockee ought to provoke implicit null check // find a free monitor BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base(); @@ -911,6 +916,7 @@ /* load from local variable */ CASE(_aload): + VERIFY_OOP(LOCALS_OBJECT(pc[1])); SET_STACK_OBJECT(LOCALS_OBJECT(pc[1]), 0); UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); @@ -930,6 +936,7 @@ #undef OPC_LOAD_n #define OPC_LOAD_n(num) \ CASE(_aload_##num): \ + VERIFY_OOP(LOCALS_OBJECT(num)); \ SET_STACK_OBJECT(LOCALS_OBJECT(num), 0); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); \ \ @@ -975,6 +982,7 @@ opcode = pc[1]; switch(opcode) { case Bytecodes::_aload: + VERIFY_OOP(LOCALS_OBJECT(reg)); SET_STACK_OBJECT(LOCALS_OBJECT(reg), 0); UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1); @@ -1099,7 +1107,7 @@ CASE(_i##opcname): \ if (test && (STACK_INT(-1) == 0)) { \ VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \ - "/ by int zero"); \ + "/ by zero"); \ } \ SET_STACK_INT(VMint##opname(STACK_INT(-2), \ STACK_INT(-1)), \ @@ -1277,7 +1285,12 @@ jfloat f; jdouble r; f = STACK_FLOAT(-1); +#ifdef IA64 + // IA64 gcc bug + r = ( f == 0.0f ) ? (jdouble) f : (jdouble) f + ia64_double_zero; +#else r = (jdouble) f; +#endif MORE_STACK(-1); // POP SET_STACK_DOUBLE(r, 1); UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); @@ -1471,6 +1484,7 @@ CASE(_return_register_finalizer): { oop rcvr = LOCALS_OBJECT(0); + VERIFY_OOP(rcvr); if (rcvr->klass()->klass_part()->has_finalizer()) { CALL_VM(InterpreterRuntime::register_finalizer(THREAD, rcvr), handle_exception); } @@ -1561,6 +1575,7 @@ */ CASE(_aastore): { oop rhsObject = STACK_OBJECT(-1); + VERIFY_OOP(rhsObject); ARRAY_INTRO( -3); // arrObj, index are set if (rhsObject != NULL) { @@ -1703,6 +1718,7 @@ obj = (oop)NULL; } else { obj = (oop) STACK_OBJECT(-1); + VERIFY_OOP(obj); } CALL_VM(InterpreterRuntime::post_field_access(THREAD, obj, @@ -1728,6 +1744,7 @@ int field_offset = cache->f2(); if (cache->is_volatile()) { if (tos_type == atos) { + VERIFY_OOP(obj->obj_field_acquire(field_offset)); SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); } else if (tos_type == itos) { SET_STACK_INT(obj->int_field_acquire(field_offset), -1); @@ -1748,6 +1765,7 @@ } } else { if (tos_type == atos) { + VERIFY_OOP(obj->obj_field(field_offset)); SET_STACK_OBJECT(obj->obj_field(field_offset), -1); } else if (tos_type == itos) { SET_STACK_INT(obj->int_field(field_offset), -1); @@ -1799,6 +1817,7 @@ } else { obj = (oop) STACK_OBJECT(-2); } + VERIFY_OOP(obj); } CALL_VM(InterpreterRuntime::post_field_modification(THREAD, @@ -1837,6 +1856,7 @@ if (tos_type == itos) { obj->release_int_field_put(field_offset, STACK_INT(-1)); } else if (tos_type == atos) { + VERIFY_OOP(STACK_OBJECT(-1)); obj->release_obj_field_put(field_offset, STACK_OBJECT(-1)); OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); } else if (tos_type == btos) { @@ -1857,6 +1877,7 @@ if (tos_type == itos) { obj->int_field_put(field_offset, STACK_INT(-1)); } else if (tos_type == atos) { + VERIFY_OOP(STACK_OBJECT(-1)); obj->obj_field_put(field_offset, STACK_OBJECT(-1)); OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); } else if (tos_type == btos) { @@ -1961,6 +1982,7 @@ } CASE(_checkcast): if (STACK_OBJECT(-1) != NULL) { + VERIFY_OOP(STACK_OBJECT(-1)); u2 index = Bytes::get_Java_u2(pc+1); if (ProfileInterpreter) { // needs Profile_checkcast QQQ @@ -1999,6 +2021,7 @@ if (STACK_OBJECT(-1) == NULL) { SET_STACK_INT(0, -1); } else { + VERIFY_OOP(STACK_OBJECT(-1)); u2 index = Bytes::get_Java_u2(pc+1); // Constant pool may have actual klass or unresolved klass. If it is // unresolved we must resolve it @@ -2044,10 +2067,12 @@ break; case JVM_CONSTANT_String: + VERIFY_OOP(constants->resolved_string_at(index)); SET_STACK_OBJECT(constants->resolved_string_at(index), 0); break; case JVM_CONSTANT_Class: + VERIFY_OOP(constants->resolved_klass_at(index)->klass_part()->java_mirror()); SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0); break; @@ -2059,17 +2084,6 @@ THREAD->set_vm_result(NULL); break; -#if 0 - CASE(_fast_igetfield): - CASE(_fastagetfield): - CASE(_fast_aload_0): - CASE(_fast_iaccess_0): - CASE(__fast_aaccess_0): - CASE(_fast_linearswitch): - CASE(_fast_binaryswitch): - fatal("unsupported fast bytecode"); -#endif - default: ShouldNotReachHere(); } UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); @@ -2122,6 +2136,7 @@ // get receiver int parms = cache->parameter_size(); // Same comments as invokevirtual apply here + VERIFY_OOP(STACK_OBJECT(-parms)); instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part(); callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; @@ -2205,6 +2220,7 @@ // this fails with an assert // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass()); // but this works + VERIFY_OOP(STACK_OBJECT(-parms)); instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part(); /* Executing this code in java.lang.String: @@ -2651,14 +2667,14 @@ LOCALS_SLOT(METHOD->size_of_parameters() - 1)); THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); } - UPDATE_PC_AND_RETURN(1); - } else { - // Normal return - // Advance the pc and return to frame manager - istate->set_msg(return_from_method); - istate->set_return_kind((Bytecodes::Code)opcode); - UPDATE_PC_AND_RETURN(1); + THREAD->clr_pop_frame_in_process(); } + + // Normal return + // Advance the pc and return to frame manager + istate->set_msg(return_from_method); + istate->set_return_kind((Bytecodes::Code)opcode); + UPDATE_PC_AND_RETURN(1); } /* handle_return: */ // This is really a fatal error return
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -440,7 +440,7 @@ * iushr, ishl, and ishr bytecodes, respectively. */ -static jint VMintUshr(jint op, jint num); +static juint VMintUshr(jint op, jint num); static jint VMintShl (jint op, jint num); static jint VMintShr (jint op, jint num);
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -27,14 +27,11 @@ #ifdef CC_INTERP #ifdef ASSERT -extern "C" { typedef void (*verify_oop_fn_t)(oop, const char *);}; -#define VERIFY_OOP(o) \ - /*{ verify_oop_fn_t verify_oop_entry = \ - *StubRoutines::verify_oop_subroutine_entry_address(); \ - if (verify_oop_entry) { \ - (*verify_oop_entry)((o), "Not an oop!"); \ - } \ - }*/ +#define VERIFY_OOP(o_) \ + if (VerifyOops) { \ + assert((oop(o_))->is_oop_or_null(), "Not an oop!"); \ + StubRoutines::_verify_oop_count++; \ + } #else #define VERIFY_OOP(o) #endif
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreter.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -41,20 +41,20 @@ } -void InterpreterCodelet::print() { +void InterpreterCodelet::print_on(outputStream* st) const { if (PrintInterpreter) { - tty->cr(); - tty->print_cr("----------------------------------------------------------------------"); + st->cr(); + st->print_cr("----------------------------------------------------------------------"); } - if (description() != NULL) tty->print("%s ", description()); - if (bytecode() >= 0 ) tty->print("%d %s ", bytecode(), Bytecodes::name(bytecode())); - tty->print_cr("[" INTPTR_FORMAT ", " INTPTR_FORMAT "] %d bytes", + if (description() != NULL) st->print("%s ", description()); + if (bytecode() >= 0 ) st->print("%d %s ", bytecode(), Bytecodes::name(bytecode())); + st->print_cr("[" INTPTR_FORMAT ", " INTPTR_FORMAT "] %d bytes", code_begin(), code_end(), code_size()); if (PrintInterpreter) { - tty->cr(); - Disassembler::decode(code_begin(), code_end(), tty); + st->cr(); + Disassembler::decode(code_begin(), code_end(), st); } }
--- a/hotspot/src/share/vm/interpreter/interpreter.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreter.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -52,7 +52,8 @@ // Debugging void verify(); - void print(); + void print_on(outputStream* st) const; + void print() const { print_on(tty); } // Interpreter-specific initialization void initialize(const char* description, Bytecodes::Code bytecode);
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -281,9 +281,7 @@ public: void pass_int() { /* ignore */ } void pass_long() { /* ignore */ } -#if defined(_LP64) || defined(ZERO) void pass_float() { /* ignore */ } -#endif void pass_double() { /* ignore */ } void pass_object() { set_one(offset()); }
--- a/hotspot/src/share/vm/memory/allocation.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/memory/allocation.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -43,24 +43,73 @@ switch (type) { case C_HEAP: res = (address)AllocateHeap(size, "C_Heap: ResourceOBJ"); + DEBUG_ONLY(set_allocation_type(res, C_HEAP);) break; case RESOURCE_AREA: + // new(size) sets allocation type RESOURCE_AREA. res = (address)operator new(size); break; default: ShouldNotReachHere(); } - // Set allocation type in the resource object for assertion checks. - DEBUG_ONLY(((ResourceObj *)res)->_allocation = type;) return res; } void ResourceObj::operator delete(void* p) { assert(((ResourceObj *)p)->allocated_on_C_heap(), "delete only allowed for C_HEAP objects"); + DEBUG_ONLY(((ResourceObj *)p)->_allocation = badHeapOopVal;) FreeHeap(p); } +#ifdef ASSERT +void ResourceObj::set_allocation_type(address res, allocation_type type) { + // Set allocation type in the resource object + uintptr_t allocation = (uintptr_t)res; + assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least"); + assert(type <= allocation_mask, "incorrect allocation type"); + ((ResourceObj *)res)->_allocation = ~(allocation + type); +} + +ResourceObj::allocation_type ResourceObj::get_allocation_type() const { + assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object"); + return (allocation_type)((~_allocation) & allocation_mask); +} + +ResourceObj::ResourceObj() { // default constructor + if (~(_allocation | allocation_mask) != (uintptr_t)this) { + set_allocation_type((address)this, STACK_OR_EMBEDDED); + } else if (allocated_on_stack()) { + // For some reason we got a value which looks like an allocation on stack. + // Pass if it is really allocated on stack. + assert(Thread::current()->on_local_stack((address)this),"should be on stack"); + } else { + assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(), + "allocation_type should be set by operator new()"); + } +} + +ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor + // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. + set_allocation_type((address)this, STACK_OR_EMBEDDED); +} + +ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment + // Used in InlineTree::ok_to_inline() for WarmCallInfo. + assert(allocated_on_stack(), "copy only into local"); + // Keep current _allocation value; + return *this; +} + +ResourceObj::~ResourceObj() { + // allocated_on_C_heap() also checks that encoded (in _allocation) address == this. + if (!allocated_on_C_heap()) { // ResourceObj::delete() zaps _allocation for C_heap. + _allocation = badHeapOopVal; // zap type + } +} +#endif // ASSERT + + void trace_heap_malloc(size_t size, const char* name, void* p) { // A lock is not needed here - tty uses a lock internally tty->print_cr("Heap malloc " INTPTR_FORMAT " %7d %s", p, size, name == NULL ? "" : name); @@ -166,32 +215,40 @@ _medium_pool = new ChunkPool(Chunk::medium_size + Chunk::aligned_overhead_size()); _small_pool = new ChunkPool(Chunk::init_size + Chunk::aligned_overhead_size()); } + + static void clean() { + enum { BlocksToKeep = 5 }; + _small_pool->free_all_but(BlocksToKeep); + _medium_pool->free_all_but(BlocksToKeep); + _large_pool->free_all_but(BlocksToKeep); + } }; ChunkPool* ChunkPool::_large_pool = NULL; ChunkPool* ChunkPool::_medium_pool = NULL; ChunkPool* ChunkPool::_small_pool = NULL; - void chunkpool_init() { ChunkPool::initialize(); } +void +Chunk::clean_chunk_pool() { + ChunkPool::clean(); +} + //-------------------------------------------------------------------------------------- // ChunkPoolCleaner implementation +// class ChunkPoolCleaner : public PeriodicTask { - enum { CleaningInterval = 5000, // cleaning interval in ms - BlocksToKeep = 5 // # of extra blocks to keep - }; + enum { CleaningInterval = 5000 }; // cleaning interval in ms public: ChunkPoolCleaner() : PeriodicTask(CleaningInterval) {} void task() { - ChunkPool::small_pool()->free_all_but(BlocksToKeep); - ChunkPool::medium_pool()->free_all_but(BlocksToKeep); - ChunkPool::large_pool()->free_all_but(BlocksToKeep); + ChunkPool::clean(); } };
--- a/hotspot/src/share/vm/memory/allocation.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/memory/allocation.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -174,9 +174,10 @@ // Start the chunk_pool cleaner task static void start_chunk_pool_cleaner_task(); + + static void clean_chunk_pool(); }; - //------------------------------Arena------------------------------------------ // Fast allocation of memory class Arena: public CHeapObj { @@ -316,32 +317,36 @@ // use delete to deallocate. class ResourceObj ALLOCATION_SUPER_CLASS_SPEC { public: - enum allocation_type { UNKNOWN = 0, C_HEAP, RESOURCE_AREA, ARENA }; + enum allocation_type { STACK_OR_EMBEDDED = 0, RESOURCE_AREA, C_HEAP, ARENA, allocation_mask = 0x3 }; + static void set_allocation_type(address res, allocation_type type) NOT_DEBUG_RETURN; #ifdef ASSERT private: - allocation_type _allocation; + // When this object is allocated on stack the new() operator is not + // called but garbage on stack may look like a valid allocation_type. + // Store negated 'this' pointer when new() is called to distinguish cases. + uintptr_t _allocation; public: - bool allocated_on_C_heap() { return _allocation == C_HEAP; } + allocation_type get_allocation_type() const; + bool allocated_on_stack() const { return get_allocation_type() == STACK_OR_EMBEDDED; } + bool allocated_on_res_area() const { return get_allocation_type() == RESOURCE_AREA; } + bool allocated_on_C_heap() const { return get_allocation_type() == C_HEAP; } + bool allocated_on_arena() const { return get_allocation_type() == ARENA; } + ResourceObj(); // default construtor + ResourceObj(const ResourceObj& r); // default copy construtor + ResourceObj& operator=(const ResourceObj& r); // default copy assignment + ~ResourceObj(); #endif // ASSERT public: void* operator new(size_t size, allocation_type type); void* operator new(size_t size, Arena *arena) { address res = (address)arena->Amalloc(size); - // Set allocation type in the resource object - DEBUG_ONLY(((ResourceObj *)res)->_allocation = ARENA;) + DEBUG_ONLY(set_allocation_type(res, ARENA);) return res; } void* operator new(size_t size) { address res = (address)resource_allocate_bytes(size); - // Set allocation type in the resource object - DEBUG_ONLY(((ResourceObj *)res)->_allocation = RESOURCE_AREA;) - return res; - } - void* operator new(size_t size, void* where, allocation_type type) { - void* res = where; - // Set allocation type in the resource object - DEBUG_ONLY(((ResourceObj *)res)->_allocation = type;) + DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);) return res; } void operator delete(void* p);
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ friend class VMStructs; friend class CardTableRS; friend class CheckForUnmarkedOops; // Needs access to raw card bytes. + friend class SharkBuilder; #ifndef PRODUCT // For debugging. friend class GuaranteeNotModClosure;
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -941,7 +941,9 @@ VerifyBeforeExit || PrintAssembly || tty->count() != 0 || // already printing - VerifyAfterGC, "too expensive"); + VerifyAfterGC || + VMError::fatal_error_in_progress(), "too expensive"); + #endif // This might be sped up with a cache of the last generation that // answered yes.
--- a/hotspot/src/share/vm/memory/generation.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/memory/generation.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -131,7 +131,9 @@ enum SomePublicConstants { // Generations are GenGrain-aligned and have size that are multiples of // GenGrain. - LogOfGenGrain = 16, + // Note: on ARM we add 1 bit for card_table_base to be properly aligned + // (we expect its low byte to be zero - see implementation of post_barrier) + LogOfGenGrain = 16 ARM_ONLY(+1), GenGrain = 1 << LogOfGenGrain };
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/arrayKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -179,8 +179,6 @@ return JVMTI_CLASS_STATUS_ARRAY; } -#ifndef PRODUCT - // Printing void arrayKlass::oop_print_on(oop obj, outputStream* st) { @@ -189,8 +187,6 @@ st->print_cr(" - length: %d", arrayOop(obj)->length()); } -#endif - // Verification void arrayKlass::oop_verify_on(oop obj, outputStream* st) {
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -115,20 +115,15 @@ // Return a handle. static void complete_create_array_klass(arrayKlassHandle k, KlassHandle super_klass, TRAPS); - public: - // jvm support - jint compute_modifier_flags(TRAPS) const; + // jvm support + jint compute_modifier_flags(TRAPS) const; - public: - // JVMTI support - jint jvmti_class_status() const; + // JVMTI support + jint jvmti_class_status() const; -#ifndef PRODUCT - public: // Printing void oop_print_on(oop obj, outputStream* st); -#endif - public: + // Verification void oop_verify_on(oop obj, outputStream* st); };
--- a/hotspot/src/share/vm/oops/arrayKlassKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/arrayKlassKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -151,15 +151,12 @@ } #endif // SERIALGC -#ifndef PRODUCT - // Printing void arrayKlassKlass::oop_print_on(oop obj, outputStream* st) { assert(obj->is_klass(), "must be klass"); klassKlass::oop_print_on(obj, st); } -#endif //PRODUCT void arrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_klass(), "must be klass");
--- a/hotspot/src/share/vm/oops/arrayKlassKlass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/arrayKlassKlass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -55,12 +55,9 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); - public: // Printing void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); -#endif //PRODUCT // Verification const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -154,8 +154,6 @@ } #endif // SERIALGC -#ifndef PRODUCT - // Printing void compiledICHolderKlass::oop_print_on(oop obj, outputStream* st) { @@ -166,8 +164,6 @@ st->print(" - klass: "); c->holder_klass()->print_value_on(st); st->cr(); } -#endif //PRODUCT - void compiledICHolderKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_compiledICHolder(), "must be compiledICHolder"); Klass::oop_print_value_on(obj, st);
--- a/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -68,12 +68,9 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); - public: // Printing void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); -#endif //PRODUCT // Verification const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/constMethodKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/constMethodKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -197,8 +197,6 @@ } #endif // SERIALGC -#ifndef PRODUCT - // Printing void constMethodKlass::oop_print_on(oop obj, outputStream* st) { @@ -216,8 +214,6 @@ } } -#endif //PRODUCT - // Short version of printing constMethodOop - just print the name of the // method it belongs to. void constMethodKlass::oop_print_value_on(oop obj, outputStream* st) {
--- a/hotspot/src/share/vm/oops/constMethodKlass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/constMethodKlass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -77,12 +77,9 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); - public: // Printing void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); -#endif //PRODUCT // Verify operations const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/constantPoolKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/constantPoolKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -299,8 +299,6 @@ } #endif // SERIALGC -#ifndef PRODUCT - // Printing void constantPoolKlass::oop_print_on(oop obj, outputStream* st) { @@ -392,8 +390,6 @@ st->cr(); } -#endif - void constantPoolKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_constantPool(), "must be constantPool"); constantPoolOop cp = constantPoolOop(obj);
--- a/hotspot/src/share/vm/oops/constantPoolKlass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/constantPoolKlass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -61,18 +61,13 @@ int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); // Allocation profiling support - // no idea why this is pure virtual and not in Klass ??? juint alloc_size() const { return _alloc_size; } void set_alloc_size(juint n) { _alloc_size = n; } - public: // Printing void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); -#endif - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st);
--- a/hotspot/src/share/vm/oops/cpCacheKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/cpCacheKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -248,8 +248,6 @@ } #endif // SERIALGC -#ifndef PRODUCT - void constantPoolCacheKlass::oop_print_on(oop obj, outputStream* st) { assert(obj->is_constantPoolCache(), "obj must be constant pool cache"); constantPoolCacheOop cache = (constantPoolCacheOop)obj; @@ -259,8 +257,6 @@ for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->print(st, i); } -#endif - void constantPoolCacheKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_constantPoolCache(), "obj must be constant pool cache"); constantPoolCacheOop cache = (constantPoolCacheOop)obj;
--- a/hotspot/src/share/vm/oops/cpCacheKlass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/cpCacheKlass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -61,14 +61,10 @@ juint alloc_size() const { return _alloc_size; } void set_alloc_size(juint n) { _alloc_size = n; } - public: // Printing void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); -#endif - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st);
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/generateOopMap.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -2111,7 +2111,13 @@ // We do not distinguish between different types of errors for verification // errors. Let the verifier give a better message. const char *msg = "Illegal class file encountered. Try running with -Xverify:all"; - error_work(msg, NULL); + _got_error = true; + // Append method name + char msg_buffer2[512]; + jio_snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg, + method()->name()->as_C_string()); + _exception = Exceptions::new_exception(Thread::current(), + vmSymbols::java_lang_LinkageError(), msg_buffer2); } //
--- a/hotspot/src/share/vm/oops/klass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/klass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -520,8 +520,6 @@ return 0; } -#ifndef PRODUCT - // Printing void Klass::oop_print_on(oop obj, outputStream* st) { @@ -541,8 +539,6 @@ st->cr(); } -#endif //PRODUCT - void Klass::oop_print_value_on(oop obj, outputStream* st) { // print title ResourceMark rm; // Cannot print in debug mode without this
--- a/hotspot/src/share/vm/oops/klass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/klass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -772,16 +772,12 @@ // jvm support virtual jint compute_modifier_flags(TRAPS) const; - public: // JVMTI support virtual jint jvmti_class_status() const; - public: // Printing virtual void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT virtual void oop_print_on (oop obj, outputStream* st); -#endif //PRODUCT // Verification virtual const char* internal_name() const = 0;
--- a/hotspot/src/share/vm/oops/klassKlass.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/klassKlass.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -194,16 +194,12 @@ #endif // SERIALGC -#ifndef PRODUCT - // Printing void klassKlass::oop_print_on(oop obj, outputStream* st) { Klass::oop_print_on(obj, st); } -#endif //PRODUCT - void klassKlass::oop_print_value_on(oop obj, outputStream* st) { Klass::oop_print_value_on(obj, st); }
--- a/hotspot/src/share/vm/oops/klassKlass.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/klassKlass.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -67,12 +67,9 @@ juint alloc_size() const { return _alloc_size; } void set_alloc_size(juint n) { _alloc_size = n; } - public: // Printing void oop_print_value_on(oop obj, outputStream* st); -#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); -#endif //PRODUCT // Verification const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/methodOop.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/methodOop.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -751,10 +751,14 @@ } OrderAccess::storestore(); +#ifdef SHARK + mh->_from_interpreted_entry = code->instructions_begin(); +#else mh->_from_compiled_entry = code->verified_entry_point(); OrderAccess::storestore(); // Instantly compiled code can execute. mh->_from_interpreted_entry = mh->get_i2c_entry(); +#endif // SHARK }
--- a/hotspot/src/share/vm/oops/oop.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/oops/oop.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -29,15 +29,6 @@ BarrierSet* oopDesc::_bs = NULL; -#ifdef PRODUCT -void oopDesc::print_on(outputStream* st) const {} -void oopDesc::print_address_on(outputStream* st) const {} -char* oopDesc::print_string() { return NULL; } -void oopDesc::print() {} -void oopDesc::print_address() {} - -#else //PRODUCT - void oopDesc::print_on(outputStream* st) const { if (this == NULL) { st->print_cr("NULL"); @@ -62,10 +53,6 @@ return st.as_string(); } -#endif // PRODUCT - -// The print_value functions are present in all builds, to support the disassembler. - void oopDesc::print_value() { print_value_on(tty); } @@ -83,9 +70,7 @@ st->print("NULL"); } else if (java_lang_String::is_instance(obj)) { java_lang_String::print(obj, st); -#ifndef PRODUCT if (PrintOopAddress) print_address_on(st); -#endif //PRODUCT #ifdef ASSERT } else if (!Universe::heap()->is_in(obj) || !Universe::heap()->is_in(klass())) { st->print("### BAD OOP %p ###", (address)obj);
--- a/hotspot/src/share/vm/opto/block.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/block.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -353,7 +353,8 @@ PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) : Phase(CFG), _bbs(a), - _root(r) + _root(r), + _node_latency(NULL) #ifndef PRODUCT , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) #endif
--- a/hotspot/src/share/vm/opto/block.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/block.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -374,7 +374,7 @@ float _outer_loop_freq; // Outmost loop frequency // Per node latency estimation, valid only during GCM - GrowableArray<uint> _node_latency; + GrowableArray<uint> *_node_latency; #ifndef PRODUCT bool _trace_opto_pipelining; // tracing flag
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/c2_globals.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -281,6 +281,12 @@ product(bool, InsertMemBarAfterArraycopy, true, \ "Insert memory barrier after arraycopy call") \ \ + develop(bool, SubsumeLoads, true, \ + "Attempt to compile while subsuming loads into machine instructions.") \ + \ + develop(bool, StressRecompilation, false, \ + "Recompile each compiled method without subsuming loads or escape analysis.") \ + \ /* controls for tier 1 compilations */ \ \ develop(bool, Tier1CountInvocations, true, \
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/c2compiler.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -103,13 +103,14 @@ if (!is_initialized()) { initialize(); } - bool subsume_loads = true; + bool subsume_loads = SubsumeLoads; bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables(); while (!env->failing()) { // Attempt to compile while subsuming loads into machine instructions. Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis); + // Check result and retry if appropriate. if (C.failure_reason() != NULL) { if (C.failure_reason_is(retry_no_subsuming_loads())) { @@ -127,6 +128,16 @@ // on the ciEnv via env->record_method_not_compilable(). env->record_failure(C.failure_reason()); } + if (StressRecompilation) { + if (subsume_loads) { + subsume_loads = false; + continue; // retry + } + if (do_escape_analysis) { + do_escape_analysis = false; + continue; // retry + } + } // No retry; just break the loop. break;
--- a/hotspot/src/share/vm/opto/chaitin.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/chaitin.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -569,7 +569,7 @@ if (trace_spilling() && lrg._def != NULL) { // collect defs for MultiDef printing if (lrg._defs == NULL) { - lrg._defs = new (_ifg->_arena) GrowableArray<Node*>(); + lrg._defs = new (_ifg->_arena) GrowableArray<Node*>(_ifg->_arena, 2, 0, NULL); lrg._defs->append(lrg._def); } lrg._defs->append(n);
--- a/hotspot/src/share/vm/opto/compile.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/compile.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -904,8 +904,8 @@ probe_alias_cache(NULL)->_index = AliasIdxTop; _intrinsics = NULL; - _macro_nodes = new GrowableArray<Node*>(comp_arena(), 8, 0, NULL); - _predicate_opaqs = new GrowableArray<Node*>(comp_arena(), 8, 0, NULL); + _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); + _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); register_library_intrinsics(); }
--- a/hotspot/src/share/vm/opto/gcm.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/gcm.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -841,7 +841,7 @@ #ifndef PRODUCT if (trace_opto_pipelining()) { tty->print("# latency_to_inputs: node_latency[%d] = %d for node", - n->_idx, _node_latency.at_grow(n->_idx)); + n->_idx, _node_latency->at_grow(n->_idx)); dump(); } #endif @@ -853,7 +853,7 @@ return; uint nlen = n->len(); - uint use_latency = _node_latency.at_grow(n->_idx); + uint use_latency = _node_latency->at_grow(n->_idx); uint use_pre_order = _bbs[n->_idx]->_pre_order; for ( uint j=0; j<nlen; j++ ) { @@ -884,15 +884,15 @@ uint delta_latency = n->latency(j); uint current_latency = delta_latency + use_latency; - if (_node_latency.at_grow(def->_idx) < current_latency) { - _node_latency.at_put_grow(def->_idx, current_latency); + if (_node_latency->at_grow(def->_idx) < current_latency) { + _node_latency->at_put_grow(def->_idx, current_latency); } #ifndef PRODUCT if (trace_opto_pipelining()) { tty->print_cr("# %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d", use_latency, j, delta_latency, current_latency, def->_idx, - _node_latency.at_grow(def->_idx)); + _node_latency->at_grow(def->_idx)); } #endif } @@ -926,7 +926,7 @@ return 0; uint nlen = use->len(); - uint nl = _node_latency.at_grow(use->_idx); + uint nl = _node_latency->at_grow(use->_idx); for ( uint j=0; j<nlen; j++ ) { if (use->in(j) == n) { @@ -962,7 +962,7 @@ #ifndef PRODUCT if (trace_opto_pipelining()) { tty->print("# latency_from_outputs: node_latency[%d] = %d for node", - n->_idx, _node_latency.at_grow(n->_idx)); + n->_idx, _node_latency->at_grow(n->_idx)); dump(); } #endif @@ -975,7 +975,7 @@ if (latency < l) latency = l; } - _node_latency.at_put_grow(n->_idx, latency); + _node_latency->at_put_grow(n->_idx, latency); } //------------------------------hoist_to_cheaper_block------------------------- @@ -985,9 +985,9 @@ const double delta = 1+PROB_UNLIKELY_MAG(4); Block* least = LCA; double least_freq = least->_freq; - uint target = _node_latency.at_grow(self->_idx); - uint start_latency = _node_latency.at_grow(LCA->_nodes[0]->_idx); - uint end_latency = _node_latency.at_grow(LCA->_nodes[LCA->end_idx()]->_idx); + uint target = _node_latency->at_grow(self->_idx); + uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx); + uint end_latency = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx); bool in_latency = (target <= start_latency); const Block* root_block = _bbs[_root->_idx]; @@ -1005,7 +1005,7 @@ #ifndef PRODUCT if (trace_opto_pipelining()) { tty->print("# Find cheaper block for latency %d: ", - _node_latency.at_grow(self->_idx)); + _node_latency->at_grow(self->_idx)); self->dump(); tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g", LCA->_pre_order, @@ -1032,9 +1032,9 @@ if (mach && LCA == root_block) break; - uint start_lat = _node_latency.at_grow(LCA->_nodes[0]->_idx); + uint start_lat = _node_latency->at_grow(LCA->_nodes[0]->_idx); uint end_idx = LCA->end_idx(); - uint end_lat = _node_latency.at_grow(LCA->_nodes[end_idx]->_idx); + uint end_lat = _node_latency->at_grow(LCA->_nodes[end_idx]->_idx); double LCA_freq = LCA->_freq; #ifndef PRODUCT if (trace_opto_pipelining()) { @@ -1073,7 +1073,7 @@ tty->print_cr("# Change latency for [%4d] from %d to %d", self->_idx, target, end_latency); } #endif - _node_latency.at_put_grow(self->_idx, end_latency); + _node_latency->at_put_grow(self->_idx, end_latency); partial_latency_of_defs(self); } @@ -1255,8 +1255,7 @@ // Compute the latency information (via backwards walk) for all the // instructions in the graph - GrowableArray<uint> node_latency; - _node_latency = node_latency; + _node_latency = new GrowableArray<uint>(); // resource_area allocation if( C->do_scheduling() ) ComputeLatenciesBackwards(visited, stack); @@ -1341,6 +1340,8 @@ } } #endif + // Dead. + _node_latency = (GrowableArray<uint> *)0xdeadbeef; }
--- a/hotspot/src/share/vm/opto/lcm.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/lcm.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -113,7 +113,8 @@ if( !m->is_Mach() ) continue; MachNode *mach = m->as_Mach(); was_store = false; - switch( mach->ideal_Opcode() ) { + int iop = mach->ideal_Opcode(); + switch( iop ) { case Op_LoadB: case Op_LoadUS: case Op_LoadD: @@ -155,6 +156,12 @@ default: // Also check for embedded loads if( !mach->needs_anti_dependence_check() ) continue; // Not an memory op; skip it + if( must_clone[iop] ) { + // Do not move nodes which produce flags because + // RA will try to clone it to place near branch and + // it will cause recompilation, see clone_node(). + continue; + } { // Check that value is used in memory address in // instructions with embedded load (CmpP val1,(val2+off)). @@ -461,7 +468,7 @@ n_choice = 1; } - uint n_latency = cfg->_node_latency.at_grow(n->_idx); + uint n_latency = cfg->_node_latency->at_grow(n->_idx); uint n_score = n->req(); // Many inputs get high score to break ties // Keep best latency found @@ -738,7 +745,7 @@ Node *n = _nodes[j]; int idx = n->_idx; tty->print("# ready cnt:%3d ", ready_cnt[idx]); - tty->print("latency:%3d ", cfg->_node_latency.at_grow(idx)); + tty->print("latency:%3d ", cfg->_node_latency->at_grow(idx)); tty->print("%4d: %s\n", idx, n->Name()); } } @@ -765,7 +772,7 @@ #ifndef PRODUCT if (cfg->trace_opto_pipelining()) { tty->print("# select %d: %s", n->_idx, n->Name()); - tty->print(", latency:%d", cfg->_node_latency.at_grow(n->_idx)); + tty->print(", latency:%d", cfg->_node_latency->at_grow(n->_idx)); n->dump(); if (Verbose) { tty->print("# ready list:"); @@ -957,6 +964,8 @@ Block *sb = _succs[i]; // Clone the entire area; ignoring the edge fixup for now. for( uint j = end; j > beg; j-- ) { + // It is safe here to clone a node with anti_dependence + // since clones dominate on each path. Node *clone = _nodes[j-1]->clone(); sb->_nodes.insert( 1, clone ); bbs.map(clone->_idx,sb);
--- a/hotspot/src/share/vm/opto/macro.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/macro.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -720,7 +720,7 @@ if (basic_elem_type == T_OBJECT || basic_elem_type == T_ARRAY) { if (!elem_type->is_loaded()) { field_type = TypeInstPtr::BOTTOM; - } else if (field != NULL && field->is_constant()) { + } else if (field != NULL && field->is_constant() && field->is_static()) { // This can happen if the constant oop is non-perm. ciObject* con = field->constant_value().as_object(); // Do not "join" in the previous type; it doesn't add value,
--- a/hotspot/src/share/vm/opto/output.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/output.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -382,6 +382,10 @@ if (min_offset_from_last_call == 0) { blk_size += nop_size; } + } else if (mach->ideal_Opcode() == Op_Jump) { + const_size += b->_num_succs; // Address table size + // The size is valid even for 64 bit since it is + // multiplied by 2*jintSize on this method exit. } } min_offset_from_last_call += inst_size;
--- a/hotspot/src/share/vm/opto/reg_split.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/opto/reg_split.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -271,6 +271,32 @@ return maxlrg; } +//------------------------------clone_node---------------------------- +// Clone node with anti dependence check. +Node* clone_node(Node* def, Block *b, Compile* C) { + if (def->needs_anti_dependence_check()) { +#ifdef ASSERT + if (Verbose) { + tty->print_cr("RA attempts to clone node with anti_dependence:"); + def->dump(-1); tty->cr(); + tty->print_cr("into block:"); + b->dump(); + } +#endif + if (C->subsume_loads() == true && !C->failing()) { + // Retry with subsume_loads == false + // If this is the first failure, the sentinel string will "stick" + // to the Compile object, and the C2Compiler will see it and retry. + C->record_failure(C2Compiler::retry_no_subsuming_loads()); + } else { + // Bailout without retry + C->record_method_not_compilable("RA Split failed: attempt to clone node with anti_dependence"); + } + return 0; + } + return def->clone(); +} + //------------------------------split_Rematerialize---------------------------- // Clone a local copy of the def. Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru ) { @@ -298,8 +324,8 @@ } } - Node *spill = def->clone(); - if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { + Node *spill = clone_node(def, b, C); + if (spill == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { // Check when generating nodes return 0; } @@ -834,13 +860,13 @@ // The effect of this clone is to drop the node out of the block, // so that the allocator does not see it anymore, and therefore // does not attempt to assign it a register. - def = def->clone(); + def = clone_node(def, b, C); + if (def == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { + return 0; + } _names.extend(def->_idx,0); _cfg._bbs.map(def->_idx,b); n->set_req(inpidx, def); - if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { - return 0; - } continue; }
--- a/hotspot/src/share/vm/prims/jni.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/prims/jni.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -3414,6 +3414,8 @@ thread->initialize_tlab(); + thread->cache_global_variables(); + // Crucial that we do not have a safepoint check for this thread, since it has // not been added to the Thread list yet. { Threads_lock->lock_without_safepoint_check();
--- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -24,6 +24,8 @@ #ifndef _JAVA_JVMTIENVTHREADSTATE_H_ #define _JAVA_JVMTIENVTHREADSTATE_H_ +class JvmtiEnv; + /////////////////////////////////////////////////////////////// // // class JvmtiFramePop
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -2593,6 +2593,12 @@ FLAG_IS_DEFAULT(UseVMInterruptibleIO)) { FLAG_SET_DEFAULT(UseVMInterruptibleIO, true); } +#ifdef LINUX + if (JDK_Version::current().compare_major(6) <= 0 && + FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) { + FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false); + } +#endif // LINUX return JNI_OK; } @@ -2659,6 +2665,28 @@ } #endif + // If we are running in a headless jre, force java.awt.headless property + // to be true unless the property has already been set. + // Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state. + if (os::is_headless_jre()) { + const char* headless = Arguments::get_property("java.awt.headless"); + if (headless == NULL) { + char envbuffer[128]; + if (!os::getenv("JAVA_AWT_HEADLESS", envbuffer, sizeof(envbuffer))) { + if (!add_property("java.awt.headless=true")) { + return JNI_ENOMEM; + } + } else { + char buffer[256]; + strcpy(buffer, "java.awt.headless="); + strcat(buffer, envbuffer); + if (!add_property(buffer)) { + return JNI_ENOMEM; + } + } + } + } + if (!check_vm_args_consistency()) { return JNI_ERR; } @@ -2979,6 +3007,14 @@ CommandLineFlags::printFlags(); } + // Apply CPU specific policy for the BiasedLocking + if (UseBiasedLocking) { + if (!VM_Version::use_biased_locking() && + !(FLAG_IS_CMDLINE(UseBiasedLocking))) { + UseBiasedLocking = false; + } + } + return JNI_OK; }
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -254,6 +254,7 @@ } +#ifndef SHARK // Compute the caller frame based on the sender sp of stub_frame and stored frame sizes info. CodeBlob* cb = stub_frame.cb(); // Verify we have the right vframeArray @@ -270,6 +271,10 @@ assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking"); Events::log("fetch unroll sp " INTPTR_FORMAT, unpack_sp); #endif +#else + intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp(); +#endif // !SHARK + // This is a guarantee instead of an assert because if vframe doesn't match // we will unpack the wrong deoptimized frame and wind up in strange places // where it will be very difficult to figure out what went wrong. Better @@ -380,7 +385,9 @@ frame_pcs[0] = deopt_sender.raw_pc(); +#ifndef SHARK assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc"); +#endif // SHARK UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, caller_adjustment * BytesPerWord, @@ -1073,7 +1080,7 @@ JRT_END -#ifdef COMPILER2 +#if defined(COMPILER2) || defined(SHARK) void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { // in case of an unresolved klass entry, load the class. if (constant_pool->tag_at(index).is_unresolved_klass()) { @@ -1835,7 +1842,7 @@ if (xtty != NULL) xtty->tail("statistics"); } } -#else // COMPILER2 +#else // COMPILER2 || SHARK // Stubs for C1 only system. @@ -1871,4 +1878,4 @@ return buf; } -#endif // COMPILER2 +#endif // COMPILER2 || SHARK
--- a/hotspot/src/share/vm/runtime/frame.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/frame.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -876,6 +876,7 @@ #endif /* CC_INTERP */ +#ifndef PPC if (m->is_native()) { #ifdef CC_INTERP f->do_oop((oop*)&istate->_oop_temp); @@ -883,6 +884,11 @@ f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset )); #endif /* CC_INTERP */ } +#else // PPC + if (m->is_native() && m->is_static()) { + f->do_oop(interpreter_frame_mirror_addr()); + } +#endif // PPC int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); @@ -1094,6 +1100,10 @@ oops_entry_do(f, map); } else if (CodeCache::contains(pc())) { oops_code_blob_do(f, cf, map); +#ifdef SHARK + } else if (is_fake_stub_frame()) { + // nothing to do +#endif // SHARK } else { ShouldNotReachHere(); }
--- a/hotspot/src/share/vm/runtime/frame.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/frame.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -25,6 +25,7 @@ typedef class BytecodeInterpreter* interpreterState; class CodeBlob; +class vframeArray; // A frame represents a physical stack frame (an activation). Frames @@ -296,6 +297,9 @@ void interpreter_frame_set_method(methodOop method); methodOop* interpreter_frame_method_addr() const; constantPoolCacheOop* interpreter_frame_cache_addr() const; +#ifdef PPC + oop* interpreter_frame_mirror_addr() const; +#endif public: // Entry frames
--- a/hotspot/src/share/vm/runtime/globals.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/globals.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -181,6 +181,18 @@ #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 notproduct}", DEFAULT }, #endif +#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark product}", DEFAULT }, +#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{Shark pd product}", DEFAULT }, +#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark diagnostic}", DEFAULT }, +#ifdef PRODUCT + #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ + #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ + #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) +#else + #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark}", DEFAULT }, + #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{Shark pd}", DEFAULT }, + #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark notproduct}", DEFAULT }, +#endif static Flag flagTable[] = { RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT) @@ -194,6 +206,9 @@ #ifdef COMPILER2 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT) #endif +#ifdef SHARK + SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT) +#endif {0, NULL, NULL} };
--- a/hotspot/src/share/vm/runtime/globals.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -22,7 +22,7 @@ * */ -#if !defined(COMPILER1) && !defined(COMPILER2) +#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) define_pd_global(bool, BackgroundCompilation, false); define_pd_global(bool, UseTLAB, false); define_pd_global(bool, CICompileOSR, false); @@ -607,7 +607,7 @@ notproduct(bool, PrintMallocFree, false, \ "Trace calls to C heap malloc/free allocation") \ \ - notproduct(bool, PrintOopAddress, false, \ + product(bool, PrintOopAddress, false, \ "Always print the location of the oop") \ \ notproduct(bool, VerifyCodeCacheOften, false, \ @@ -2442,6 +2442,10 @@ "Call fatal if this exception is thrown. Example: " \ "java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \ \ + notproduct(ccstr, AbortVMOnExceptionMessage, NULL, \ + "Call fatal if the exception pointed by AbortVMOnException " \ + "has this message.") \ + \ develop(bool, DebugVtables, false, \ "add debugging code to vtable dispatch") \ \ @@ -3554,7 +3558,6 @@ "EINTR for I/O operations results in OS_INTRPT. The default value"\ " of this flag is true for JDK 6 and earliers") - /* * Macros for factoring of globals */
--- a/hotspot/src/share/vm/runtime/java.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/java.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -378,7 +378,8 @@ } // Terminate watcher thread - must before disenrolling any periodic task - WatcherThread::stop(); + if (PeriodicTask::num_tasks() > 0) + WatcherThread::stop(); // Print statistics gathered (profiling ...) if (Arguments::has_profile()) {
--- a/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -76,7 +76,6 @@ JavaFrameAnchor() { clear(); } JavaFrameAnchor(JavaFrameAnchor *src) { copy(src); } - address last_Java_pc(void) { return _last_Java_pc; } void set_last_Java_pc(address pc) { _last_Java_pc = pc; } // Assembly stub generation helpers
--- a/hotspot/src/share/vm/runtime/os.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/os.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -735,6 +735,152 @@ st->print_cr("elapsed time: %d seconds", (int)t); } +// moved from debug.cpp (used to be find()) but still called from there +// The print_pc parameter is only set by the debug code in one case +void os::print_location(outputStream* st, intptr_t x, bool print_pc) { + address addr = (address)x; + CodeBlob* b = CodeCache::find_blob_unsafe(addr); + if (b != NULL) { + if (b->is_buffer_blob()) { + // the interpreter is generated into a buffer blob + InterpreterCodelet* i = Interpreter::codelet_containing(addr); + if (i != NULL) { + i->print_on(st); + return; + } + if (Interpreter::contains(addr)) { + st->print_cr(INTPTR_FORMAT " is pointing into interpreter code" + " (not bytecode specific)", addr); + return; + } + // + if (AdapterHandlerLibrary::contains(b)) { + st->print_cr("Printing AdapterHandler"); + AdapterHandlerLibrary::print_handler_on(st, b); + } + // the stubroutines are generated into a buffer blob + StubCodeDesc* d = StubCodeDesc::desc_for(addr); + if (d != NULL) { + d->print_on(st); + if (print_pc) st->cr(); + return; + } + if (StubRoutines::contains(addr)) { + st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) " + "stub routine", addr); + return; + } + // the InlineCacheBuffer is using stubs generated into a buffer blob + if (InlineCacheBuffer::contains(addr)) { + st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr); + return; + } + VtableStub* v = VtableStubs::stub_containing(addr); + if (v != NULL) { + v->print_on(st); + return; + } + } + if (print_pc && b->is_nmethod()) { + ResourceMark rm; + st->print("%#p: Compiled ", addr); + ((nmethod*)b)->method()->print_value_on(st); + st->print(" = (CodeBlob*)" INTPTR_FORMAT, b); + st->cr(); + return; + } + if ( b->is_nmethod()) { + if (b->is_zombie()) { + st->print_cr(INTPTR_FORMAT " is zombie nmethod", b); + } else if (b->is_not_entrant()) { + st->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b); + } + } + b->print_on(st); + return; + } + + if (Universe::heap()->is_in(addr)) { + HeapWord* p = Universe::heap()->block_start(addr); + bool print = false; + // If we couldn't find it it just may mean that heap wasn't parseable + // See if we were just given an oop directly + if (p != NULL && Universe::heap()->block_is_obj(p)) { + print = true; + } else if (p == NULL && ((oopDesc*)addr)->is_oop()) { + p = (HeapWord*) addr; + print = true; + } + if (print) { + oop(p)->print_on(st); + if (p != (HeapWord*)x && oop(p)->is_constMethod() && + constMethodOop(p)->contains(addr)) { + Thread *thread = Thread::current(); + HandleMark hm(thread); + methodHandle mh (thread, constMethodOop(p)->method()); + if (!mh->is_native()) { + st->print_cr("bci_from(%p) = %d; print_codes():", + addr, mh->bci_from(address(x))); + mh->print_codes_on(st); + } + } + return; + } + } else { + if (Universe::heap()->is_in_reserved(addr)) { + st->print_cr(INTPTR_FORMAT " is an unallocated location " + "in the heap", addr); + return; + } + } + if (JNIHandles::is_global_handle((jobject) addr)) { + st->print_cr(INTPTR_FORMAT " is a global jni handle", addr); + return; + } + if (JNIHandles::is_weak_global_handle((jobject) addr)) { + st->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr); + return; + } +#ifndef PRODUCT + // we don't keep the block list in product mode + if (JNIHandleBlock::any_contains((jobject) addr)) { + st->print_cr(INTPTR_FORMAT " is a local jni handle", addr); + return; + } +#endif + + for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { + // Check for privilege stack + if (thread->privileged_stack_top() != NULL && + thread->privileged_stack_top()->contains(addr)) { + st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack " + "for thread: " INTPTR_FORMAT, addr, thread); + thread->print_on(st); + return; + } + // If the addr is a java thread print information about that. + if (addr == (address)thread) { + thread->print_on(st); + return; + } + // If the addr is in the stack region for this thread then report that + // and print thread info + if (thread->stack_base() >= addr && + addr > (thread->stack_base() - thread->stack_size())) { + st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: " + INTPTR_FORMAT, addr, thread); + thread->print_on(st); + return; + } + + } + // Try an OS specific find + if (os::find(addr, st)) { + return; + } + + st->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr); +} // Looks like all platforms except IA64 can use the same function to check // if C stack is walkable beyond current frame. The check for fp() is not
--- a/hotspot/src/share/vm/runtime/os.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/os.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,8 +78,10 @@ } public: - static void init(void); // Called before command line parsing - static jint init_2(void); // Called after command line parsing + + static void init(void); // Called before command line parsing + static jint init_2(void); // Called after command line parsing + static void init_3(void); // Called at the end of vm init // File names are case-insensitive on windows only // Override me as needed @@ -322,7 +324,8 @@ pgc_thread, // Parallel GC thread java_thread, compiler_thread, - watcher_thread + watcher_thread, + os_thread }; static bool create_thread(Thread* thread, @@ -451,6 +454,8 @@ static void print_signal_handlers(outputStream* st, char* buf, size_t buflen); static void print_date_and_time(outputStream* st); + static void print_location(outputStream* st, intptr_t x, bool print_pc = false); + // The following two functions are used by fatal error handler to trace // native (C) frames. They are not part of frame.hpp/frame.cpp because // frame.hpp/cpp assume thread is JavaThread, and also because different @@ -480,6 +485,9 @@ // Fills in path to jvm.dll/libjvm.so (this info used to find hpi). static void jvm_path(char *buf, jint buflen); + // Returns true if we are running in a headless jre. + static bool is_headless_jre(); + // JNI names static void print_jni_name_prefix_on(outputStream* st, int args_size); static void print_jni_name_suffix_on(outputStream* st, int args_size); @@ -580,8 +588,8 @@ // Platform dependent stuff #include "incls/_os_pd.hpp.incl" - // debugging support (mostly used by debug.cpp) - static bool find(address pc) PRODUCT_RETURN0; // OS specific function to make sense out of an address + // debugging support (mostly used by debug.cpp but also fatal error handler) + static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address static bool dont_yield(); // when true, JVM_Yield() is nop static void print_statistics();
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -191,6 +191,121 @@ return ((jdouble)fmod((double)x,(double)y)); JRT_END +#ifdef __SOFTFP__ +JRT_LEAF(jfloat, SharedRuntime::fadd(jfloat x, jfloat y)) + return x + y; +JRT_END + +JRT_LEAF(jfloat, SharedRuntime::fsub(jfloat x, jfloat y)) + return x - y; +JRT_END + +JRT_LEAF(jfloat, SharedRuntime::fmul(jfloat x, jfloat y)) + return x * y; +JRT_END + +JRT_LEAF(jfloat, SharedRuntime::fdiv(jfloat x, jfloat y)) + return x / y; +JRT_END + +JRT_LEAF(jdouble, SharedRuntime::dadd(jdouble x, jdouble y)) + return x + y; +JRT_END + +JRT_LEAF(jdouble, SharedRuntime::dsub(jdouble x, jdouble y)) + return x - y; +JRT_END + +JRT_LEAF(jdouble, SharedRuntime::dmul(jdouble x, jdouble y)) + return x * y; +JRT_END + +JRT_LEAF(jdouble, SharedRuntime::ddiv(jdouble x, jdouble y)) + return x / y; +JRT_END + +JRT_LEAF(jfloat, SharedRuntime::i2f(jint x)) + return (jfloat)x; +JRT_END + +JRT_LEAF(jdouble, SharedRuntime::i2d(jint x)) + return (jdouble)x; +JRT_END + +JRT_LEAF(jdouble, SharedRuntime::f2d(jfloat x)) + return (jdouble)x; +JRT_END + +JRT_LEAF(int, SharedRuntime::fcmpl(float x, float y)) + return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan*/ +JRT_END + +JRT_LEAF(int, SharedRuntime::fcmpg(float x, float y)) + return x<y ? -1 : (x==y ? 0 : 1); /* x>y or is_nan */ +JRT_END + +JRT_LEAF(int, SharedRuntime::dcmpl(double x, double y)) + return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan */ +JRT_END + +JRT_LEAF(int, SharedRuntime::dcmpg(double x, double y)) + return x<y ? -1 : (x==y ? 0 : 1); /* x>y or is_nan */ +JRT_END + +// Functions to return the opposite of the aeabi functions for nan. +JRT_LEAF(int, SharedRuntime::unordered_fcmplt(float x, float y)) + return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +JRT_LEAF(int, SharedRuntime::unordered_dcmplt(double x, double y)) + return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +JRT_LEAF(int, SharedRuntime::unordered_fcmple(float x, float y)) + return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +JRT_LEAF(int, SharedRuntime::unordered_dcmple(double x, double y)) + return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +JRT_LEAF(int, SharedRuntime::unordered_fcmpge(float x, float y)) + return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +JRT_LEAF(int, SharedRuntime::unordered_dcmpge(double x, double y)) + return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +JRT_LEAF(int, SharedRuntime::unordered_fcmpgt(float x, float y)) + return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +JRT_LEAF(int, SharedRuntime::unordered_dcmpgt(double x, double y)) + return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); +JRT_END + +// Intrinsics make gcc generate code for these. +float SharedRuntime::fneg(float f) { + return -f; +} + +double SharedRuntime::dneg(double f) { + return -f; +} + +#endif // __SOFTFP__ + +#if defined(__SOFTFP__) || defined(E500V2) +// Intrinsics make gcc generate code for these. +double SharedRuntime::dabs(double f) { + return (f <= (double)0.0) ? (double)0.0 - f : f; +} + +double SharedRuntime::dsqrt(double f) { + return sqrt(f); +} +#endif JRT_LEAF(jint, SharedRuntime::f2i(jfloat x)) if (g_isnan(x)) @@ -2046,6 +2161,8 @@ int AdapterHandlerTable::_hits; int AdapterHandlerTable::_compact; +#endif + class AdapterHandlerTableIterator : public StackObj { private: AdapterHandlerTable* _table; @@ -2081,7 +2198,6 @@ } } }; -#endif // --------------------------------------------------------------------------- @@ -2619,7 +2735,6 @@ FREE_C_HEAP_ARRAY(intptr_t,buf); JRT_END -#ifndef PRODUCT bool AdapterHandlerLibrary::contains(CodeBlob* b) { AdapterHandlerTableIterator iter(_adapters); while (iter.has_next()) { @@ -2629,21 +2744,24 @@ return false; } -void AdapterHandlerLibrary::print_handler(CodeBlob* b) { +void AdapterHandlerLibrary::print_handler_on(outputStream* st, CodeBlob* b) { AdapterHandlerTableIterator iter(_adapters); while (iter.has_next()) { AdapterHandlerEntry* a = iter.next(); if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) { - tty->print("Adapter for signature: "); - tty->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT, - a->fingerprint()->as_string(), - a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry()); + st->print("Adapter for signature: "); + st->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT, + a->fingerprint()->as_string(), + a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry()); + return; } } assert(false, "Should have found handler"); } +#ifndef PRODUCT + void AdapterHandlerLibrary::print_statistics() { _adapters->print_statistics(); }
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -78,6 +78,18 @@ static jfloat frem(jfloat x, jfloat y); static jdouble drem(jdouble x, jdouble y); +#ifdef __SOFTFP__ + static jfloat fadd(jfloat x, jfloat y); + static jfloat fsub(jfloat x, jfloat y); + static jfloat fmul(jfloat x, jfloat y); + static jfloat fdiv(jfloat x, jfloat y); + + static jdouble dadd(jdouble x, jdouble y); + static jdouble dsub(jdouble x, jdouble y); + static jdouble dmul(jdouble x, jdouble y); + static jdouble ddiv(jdouble x, jdouble y); +#endif // __SOFTFP__ + // float conversion (needs to set appropriate rounding mode) static jint f2i (jfloat x); static jlong f2l (jfloat x); @@ -87,6 +99,12 @@ static jfloat l2f (jlong x); static jdouble l2d (jlong x); +#ifdef __SOFTFP__ + static jfloat i2f (jint x); + static jdouble i2d (jint x); + static jdouble f2d (jfloat x); +#endif // __SOFTFP__ + // double trigonometrics and transcendentals static jdouble dsin(jdouble x); static jdouble dcos(jdouble x); @@ -96,6 +114,32 @@ static jdouble dexp(jdouble x); static jdouble dpow(jdouble x, jdouble y); +#if defined(__SOFTFP__) || defined(E500V2) + static double dabs(double f); + static double dsqrt(double f); +#endif + +#ifdef __SOFTFP__ + // C++ compiler generates soft float instructions as well as passing + // float and double in registers. + static int fcmpl(float x, float y); + static int fcmpg(float x, float y); + static int dcmpl(double x, double y); + static int dcmpg(double x, double y); + + static int unordered_fcmplt(float x, float y); + static int unordered_dcmplt(double x, double y); + static int unordered_fcmple(float x, float y); + static int unordered_dcmple(double x, double y); + static int unordered_fcmpge(float x, float y); + static int unordered_dcmpge(double x, double y); + static int unordered_fcmpgt(float x, float y); + static int unordered_dcmpgt(double x, double y); + + static float fneg(float f); + static double dneg(double f); +#endif + // exception handling across interpreter/compiler boundaries static address raw_exception_handler_for_return_address(JavaThread* thread, address return_address); static address exception_handler_for_return_address(JavaThread* thread, address return_address); @@ -585,9 +629,7 @@ bool compare_code(unsigned char* code, int length, int total_args_passed, BasicType* sig_bt); #endif -#ifndef PRODUCT void print(); -#endif /* PRODUCT */ }; class AdapterHandlerLibrary: public AllStatic { @@ -609,9 +651,10 @@ static nmethod* create_dtrace_nmethod (methodHandle method); #endif // HAVE_DTRACE_H + static void print_handler(CodeBlob* b) { print_handler_on(tty, b); } + static void print_handler_on(outputStream* st, CodeBlob* b); + static bool contains(CodeBlob* b); #ifndef PRODUCT - static void print_handler(CodeBlob* b); - static bool contains(CodeBlob* b); static void print_statistics(); #endif /* PRODUCT */
--- a/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -572,7 +572,11 @@ if(hy<0) z = one/z; /* z = (1/|x|) */ if(hx<0) { if(((ix-0x3ff00000)|yisint)==0) { +#ifdef CAN_USE_NAN_DEFINE + z = NAN; +#else z = (z-z)/(z-z); /* (-1)**non-int is NaN */ +#endif } else if(yisint==1) z = -1.0*z; /* (x<0)**odd = -(|x|**odd) */ } @@ -583,7 +587,12 @@ n = (hx>>31)+1; /* (x<0)**(non-int) is NaN */ - if((n|yisint)==0) return (x-x)/(x-x); + if((n|yisint)==0) +#ifdef CAN_USE_NAN_DEFINE + return NAN; +#else + return (x-x)/(x-x); +#endif s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
--- a/hotspot/src/share/vm/runtime/signature.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/signature.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -275,11 +275,7 @@ void do_bool () { pass_int(); _jni_offset++; _offset++; } void do_char () { pass_int(); _jni_offset++; _offset++; } -#if defined(_LP64) || defined(ZERO) void do_float () { pass_float(); _jni_offset++; _offset++; } -#else - void do_float () { pass_int(); _jni_offset++; _offset++; } -#endif #ifdef _LP64 void do_double() { pass_double(); _jni_offset++; _offset += 2; } #else @@ -306,9 +302,7 @@ virtual void pass_int() = 0; virtual void pass_long() = 0; virtual void pass_object() = 0; -#if defined(_LP64) || defined(ZERO) virtual void pass_float() = 0; -#endif #ifdef _LP64 virtual void pass_double() = 0; #else
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -53,15 +53,13 @@ } -void StubCodeDesc::print() { - tty->print(group()); - tty->print("::"); - tty->print(name()); - tty->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", begin(), end(), size_in_bytes()); +void StubCodeDesc::print_on(outputStream* st) const { + st->print(group()); + st->print("::"); + st->print(name()); + st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", begin(), end(), size_in_bytes()); } - - // Implementation of StubCodeGenerator StubCodeGenerator::StubCodeGenerator(CodeBuffer* code) {
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -79,7 +79,8 @@ address end() const { return _end; } int size_in_bytes() const { return _end - _begin; } bool contains(address pc) const { return _begin <= pc && pc < _end; } - void print(); + void print_on(outputStream* st) const; + void print() const { print_on(tty); } }; // The base class for all stub-generating code generators.
--- a/hotspot/src/share/vm/runtime/thread.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -807,7 +807,7 @@ // should be revisited, and they should be removed if possible. bool Thread::is_lock_owned(address adr) const { - return (_stack_base >= adr && adr >= (_stack_base - _stack_size)); + return on_local_stack(adr); } bool Thread::set_as_starting_thread() { @@ -1020,7 +1020,7 @@ // timer interrupts exists on the platform. WatcherThread* WatcherThread::_watcher_thread = NULL; -bool WatcherThread::_should_terminate = false; +volatile bool WatcherThread::_should_terminate = false; WatcherThread::WatcherThread() : Thread() { assert(watcher_thread() == NULL, "we can only allocate one WatcherThread"); @@ -1052,8 +1052,26 @@ // Calculate how long it'll be until the next PeriodicTask work // should be done, and sleep that amount of time. - const size_t time_to_wait = PeriodicTask::time_to_wait(); - os::sleep(this, time_to_wait, false); + size_t time_to_wait = PeriodicTask::time_to_wait(); + + // we expect this to timeout - we only ever get unparked when + // we should terminate + { + OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */); + + jlong prev_time = os::javaTimeNanos(); + for (;;) { + int res= _SleepEvent->park(time_to_wait); + if (res == OS_TIMEOUT || _should_terminate) + break; + // spurious wakeup of some kind + jlong now = os::javaTimeNanos(); + time_to_wait -= (now - prev_time) / 1000000; + if (time_to_wait <= 0) + break; + prev_time = now; + } + } if (is_error_reported()) { // A fatal error has happened, the error handler(VMError::report_and_die) @@ -1115,6 +1133,12 @@ // it is ok to take late safepoints here, if needed MutexLocker mu(Terminator_lock); _should_terminate = true; + OrderAccess::fence(); // ensure WatcherThread sees update in main loop + + Thread* watcher = watcher_thread(); + if (watcher != NULL) + watcher->_SleepEvent->unpark(); + while(watcher_thread() != NULL) { // This wait should make safepoint checks, wait without a timeout, // and wait as a suspend-equivalent condition. @@ -1364,6 +1388,8 @@ this->create_stack_guard_pages(); + this->cache_global_variables(); + // Thread is now sufficient initialized to be handled by the safepoint code as being // in the VM. Change thread state from _thread_new to _thread_in_vm ThreadStateTransition::transition_and_fence(this, _thread_new, _thread_in_vm); @@ -2955,6 +2981,9 @@ return status; } + // Should be done after the heap is fully created + main_thread->cache_global_variables(); + HandleMark hm; { MutexLocker mu(Threads_lock); @@ -3230,6 +3259,9 @@ WatcherThread::start(); } + // Give os specific code one last chance to start + os::init_3(); + create_vm_timer.end(); return JNI_OK; } @@ -3249,12 +3281,18 @@ char buffer[JVM_MAXPATHLEN]; char ebuf[1024]; const char *name = agent->name(); + const char *msg = "Could not find agent library "; if (agent->is_absolute_path()) { library = hpi::dll_load(name, ebuf, sizeof ebuf); if (library == NULL) { + const char *sub_msg = " in absolute path, with error: "; + size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1; + char *buf = NEW_C_HEAP_ARRAY(char, len); + jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf); // If we can't find the agent, exit. - vm_exit_during_initialization("Could not find agent library in absolute path", name); + vm_exit_during_initialization(buf, NULL); + FREE_C_HEAP_ARRAY(char, buf); } } else { // Try to load the agent from the standard dll directory @@ -3267,17 +3305,17 @@ char *home = Arguments::get_java_home(); const char *fmt = "%s/bin/java %s -Dkernel.background.download=false" " sun.jkernel.DownloadManager -download client_jvm"; - int length = strlen(props) + strlen(home) + strlen(fmt) + 1; - char *cmd = AllocateHeap(length); + size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1; + char *cmd = NEW_C_HEAP_ARRAY(char, length); jio_snprintf(cmd, length, fmt, home, props); int status = os::fork_and_exec(cmd); FreeHeap(props); - FreeHeap(cmd); if (status == -1) { warning(cmd); vm_exit_during_initialization("fork_and_exec failed: %s", strerror(errno)); } + FREE_C_HEAP_ARRAY(char, cmd); // when this comes back the instrument.dll should be where it belongs. library = hpi::dll_load(buffer, ebuf, sizeof ebuf); } @@ -3287,8 +3325,13 @@ hpi::dll_build_name(buffer, sizeof(buffer), ns, name); library = hpi::dll_load(buffer, ebuf, sizeof ebuf); if (library == NULL) { + const char *sub_msg = " on the library path, with error: "; + size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1; + char *buf = NEW_C_HEAP_ARRAY(char, len); + jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf); // If we can't find the agent, exit. - vm_exit_during_initialization("Could not find agent library on the library path or in the local directory", name); + vm_exit_during_initialization(buf, NULL); + FREE_C_HEAP_ARRAY(char, buf); } } }
--- a/hotspot/src/share/vm/runtime/thread.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/thread.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -410,9 +410,6 @@ // Sweeper support void nmethods_do(CodeBlobClosure* cf); - // Tells if adr belong to this thread. This is used - // for checking if a lock is owned by the running thread. - // Used by fast lock support virtual bool is_lock_owned(address adr) const; @@ -449,6 +446,11 @@ void set_stack_size(size_t size) { _stack_size = size; } void record_stack_base_and_size(); + bool on_local_stack(address adr) const { + /* QQQ this has knowledge of direction, ought to be a stack method */ + return (_stack_base >= adr && adr >= (_stack_base - _stack_size)); + } + int lgrp_id() const { return _lgrp_id; } void set_lgrp_id(int value) { _lgrp_id = value; } @@ -609,7 +611,7 @@ private: static WatcherThread* _watcher_thread; - static bool _should_terminate; + volatile static bool _should_terminate; // updated without holding lock public: enum SomeConstants { delay_interval = 10 // interrupt delay in milliseconds @@ -839,6 +841,10 @@ return (struct JNINativeInterface_ *)_jni_environment.functions; } + // This function is called at thread creation to allow + // platform specific thread variables to be initialized. + void cache_global_variables(); + // Executes Shutdown.shutdown() void invoke_shutdown_hooks();
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/vm_version.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,11 @@ #define VMTYPE "Server" #else // TIERED #ifdef ZERO +#ifdef SHARK + #define VMTYPE "Shark" +#else // SHARK #define VMTYPE "Zero" +#endif // SHARK #else // ZERO #define VMTYPE COMPILER1_PRESENT("Client") \ COMPILER2_PRESENT("Server") @@ -152,6 +156,8 @@ #define CPU IA32_ONLY("x86") \ IA64_ONLY("ia64") \ AMD64_ONLY("amd64") \ + ARM_ONLY("arm") \ + PPC_ONLY("ppc") \ SPARC_ONLY("sparc") #endif // ZERO
--- a/hotspot/src/share/vm/runtime/vm_version.hpp Wed Sep 01 17:37:45 2010 -0700 +++ b/hotspot/src/share/vm/runtime/vm_version.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -70,6 +70,9 @@ return _logical_processors_per_package; } + // ARCH specific policy for the BiasedLocking + static bool use_biased_locking() { return true; } + // Number of page sizes efficiently supported by the hardware. Most chips now // support two sizes, thus this default implementation. Processor-specific // subclasses should define new versions to hide this one as needed. Note
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/shark/llvmHeaders.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009, 2010 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifdef assert + #undef assert +#endif + +#ifdef DEBUG + #define SHARK_DEBUG + #undef DEBUG +#endif + +#include <llvm/Argument.h> +#include <llvm/Constants.h> +#include <llvm/DerivedTypes.h> +#include <llvm/ExecutionEngine/ExecutionEngine.h> +#include <llvm/Instructions.h> +#include <llvm/LLVMContext.h> +#include <llvm/Module.h> +#if SHARK_LLVM_VERSION < 27 +#include <llvm/ModuleProvider.h> +#endif +#include <llvm/Support/IRBuilder.h> +#include <llvm/System/Threading.h> +#include <llvm/Target/TargetSelect.h> +#include <llvm/Type.h> +#include <llvm/ExecutionEngine/JITMemoryManager.h> +#include <llvm/Support/CommandLine.h> +#if SHARK_LLVM_VERSION >= 27 +#include <llvm/ExecutionEngine/JIT.h> +#include <llvm/ADT/StringMap.h> +#include <llvm/Support/Debug.h> +#include <llvm/System/Host.h> +#endif + +#include <map> + +#ifdef assert + #undef assert +#endif + +// from hotspot/src/share/vm/utilities/debug.hpp +#ifdef ASSERT +#ifndef USE_REPEATED_ASSERTS +#define assert(p, msg) \ +do { \ + if (!(p)) { \ + report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \ + BREAKPOINT; \ + } \ +} while (0) +#else // #ifndef USE_REPEATED_ASSERTS +#define assert(p, msg) +do { \ + for (int __i = 0; __i < AssertRepeat; __i++) { \ + if (!(p)) { \ + report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \ + BREAKPOINT; \ + } \ + } \ +} while (0) +#endif // #ifndef USE_REPEATED_ASSERTS +#else + #define assert(p, msg) +#endif + +#ifdef DEBUG + #undef DEBUG +#endif +#ifdef SHARK_DEBUG + #define DEBUG + #undef SHARK_DEBUG +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/shark/llvmValue.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +class LLVMValue : public AllStatic { + public: + static llvm::ConstantInt* jbyte_constant(jbyte value) + { + return llvm::ConstantInt::get(SharkType::jbyte_type(), value, true); + } + static llvm::ConstantInt* jint_constant(jint value) + { + return llvm::ConstantInt::get(SharkType::jint_type(), value, true); + } + static llvm::ConstantInt* jlong_constant(jlong value) + { + return llvm::ConstantInt::get(SharkType::jlong_type(), value, true); + } + static llvm::ConstantFP* jfloat_constant(jfloat value) + { + return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value)); + } + static llvm::ConstantFP* jdouble_constant(jdouble value) + { + return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value)); + } + static llvm::ConstantPointerNull* null() + { + return llvm::ConstantPointerNull::get(SharkType::oop_type()); + } + + public: + static llvm::ConstantInt* bit_constant(int value) + { + return llvm::ConstantInt::get(SharkType::bit_type(), value, false); + } + static llvm::ConstantInt* intptr_constant(intptr_t value) + { + return llvm::ConstantInt::get(SharkType::intptr_type(), value, false); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,1260 @@ +/* + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009, 2010 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_sharkBlock.cpp.incl" + +using namespace llvm; + +void SharkBlock::parse_bytecode(int start, int limit) { + SharkValue *a, *b, *c, *d; + int i; + + // Ensure the current state is initialized before we emit any code, + // so that any setup code for the state is at the start of the block + current_state(); + + // Parse the bytecodes + iter()->reset_to_bci(start); + while (iter()->next_bci() < limit) { + NOT_PRODUCT(a = b = c = d = NULL); + iter()->next(); + + if (SharkTraceBytecodes) + tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc())); + + if (has_trap() && trap_bci() == bci()) { + do_trap(trap_request()); + return; + } + + if (UseLoopSafepoints) { + // XXX if a lcmp is followed by an if_?? then C2 maybe-inserts + // the safepoint before the lcmp rather than before the if. + // Maybe we should do this too. See parse2.cpp for details. + switch (bc()) { + case Bytecodes::_goto: + case Bytecodes::_ifnull: + case Bytecodes::_ifnonnull: + case Bytecodes::_if_acmpeq: + case Bytecodes::_if_acmpne: + case Bytecodes::_ifeq: + case Bytecodes::_ifne: + case Bytecodes::_iflt: + case Bytecodes::_ifle: + case Bytecodes::_ifgt: + case Bytecodes::_ifge: + case Bytecodes::_if_icmpeq: + case Bytecodes::_if_icmpne: + case Bytecodes::_if_icmplt: + case Bytecodes::_if_icmple: + case Bytecodes::_if_icmpgt: + case Bytecodes::_if_icmpge: + if (iter()->get_dest() <= bci()) + maybe_add_backedge_safepoint(); + break; + + case Bytecodes::_goto_w: + if (iter()->get_far_dest() <= bci()) + maybe_add_backedge_safepoint(); + break; + + case Bytecodes::_tableswitch: + case Bytecodes::_lookupswitch: + if (switch_default_dest() <= bci()) { + maybe_add_backedge_safepoint(); + break; + } + int len = switch_table_length(); + for (int i = 0; i < len; i++) { + if (switch_dest(i) <= bci()) { + maybe_add_backedge_safepoint(); + break; + } + } + break; + } + } + + switch (bc()) { + case Bytecodes::_nop: + break; + + case Bytecodes::_aconst_null: + push(SharkValue::null()); + break; + + case Bytecodes::_iconst_m1: + push(SharkValue::jint_constant(-1)); + break; + case Bytecodes::_iconst_0: + push(SharkValue::jint_constant(0)); + break; + case Bytecodes::_iconst_1: + push(SharkValue::jint_constant(1)); + break; + case Bytecodes::_iconst_2: + push(SharkValue::jint_constant(2)); + break; + case Bytecodes::_iconst_3: + push(SharkValue::jint_constant(3)); + break; + case Bytecodes::_iconst_4: + push(SharkValue::jint_constant(4)); + break; + case Bytecodes::_iconst_5: + push(SharkValue::jint_constant(5)); + break; + + case Bytecodes::_lconst_0: + push(SharkValue::jlong_constant(0)); + break; + case Bytecodes::_lconst_1: + push(SharkValue::jlong_constant(1)); + break; + + case Bytecodes::_fconst_0: + push(SharkValue::jfloat_constant(0)); + break; + case Bytecodes::_fconst_1: + push(SharkValue::jfloat_constant(1)); + break; + case Bytecodes::_fconst_2: + push(SharkValue::jfloat_constant(2)); + break; + + case Bytecodes::_dconst_0: + push(SharkValue::jdouble_constant(0)); + break; + case Bytecodes::_dconst_1: + push(SharkValue::jdouble_constant(1)); + break; + + case Bytecodes::_bipush: + push(SharkValue::jint_constant(iter()->get_constant_u1())); + break; + case Bytecodes::_sipush: + push(SharkValue::jint_constant(iter()->get_constant_u2())); + break; + + case Bytecodes::_ldc: + case Bytecodes::_ldc_w: + case Bytecodes::_ldc2_w: + push(SharkConstant::for_ldc(iter())->value(builder())); + break; + + case Bytecodes::_iload_0: + case Bytecodes::_lload_0: + case Bytecodes::_fload_0: + case Bytecodes::_dload_0: + case Bytecodes::_aload_0: + push(local(0)); + break; + case Bytecodes::_iload_1: + case Bytecodes::_lload_1: + case Bytecodes::_fload_1: + case Bytecodes::_dload_1: + case Bytecodes::_aload_1: + push(local(1)); + break; + case Bytecodes::_iload_2: + case Bytecodes::_lload_2: + case Bytecodes::_fload_2: + case Bytecodes::_dload_2: + case Bytecodes::_aload_2: + push(local(2)); + break; + case Bytecodes::_iload_3: + case Bytecodes::_lload_3: + case Bytecodes::_fload_3: + case Bytecodes::_dload_3: + case Bytecodes::_aload_3: + push(local(3)); + break; + case Bytecodes::_iload: + case Bytecodes::_lload: + case Bytecodes::_fload: + case Bytecodes::_dload: + case Bytecodes::_aload: + push(local(iter()->get_index())); + break; + + case Bytecodes::_baload: + do_aload(T_BYTE); + break; + case Bytecodes::_caload: + do_aload(T_CHAR); + break; + case Bytecodes::_saload: + do_aload(T_SHORT); + break; + case Bytecodes::_iaload: + do_aload(T_INT); + break; + case Bytecodes::_laload: + do_aload(T_LONG); + break; + case Bytecodes::_faload: + do_aload(T_FLOAT); + break; + case Bytecodes::_daload: + do_aload(T_DOUBLE); + break; + case Bytecodes::_aaload: + do_aload(T_OBJECT); + break; + + case Bytecodes::_istore_0: + case Bytecodes::_lstore_0: + case Bytecodes::_fstore_0: + case Bytecodes::_dstore_0: + case Bytecodes::_astore_0: + set_local(0, pop()); + break; + case Bytecodes::_istore_1: + case Bytecodes::_lstore_1: + case Bytecodes::_fstore_1: + case Bytecodes::_dstore_1: + case Bytecodes::_astore_1: + set_local(1, pop()); + break; + case Bytecodes::_istore_2: + case Bytecodes::_lstore_2: + case Bytecodes::_fstore_2: + case Bytecodes::_dstore_2: + case Bytecodes::_astore_2: + set_local(2, pop()); + break; + case Bytecodes::_istore_3: + case Bytecodes::_lstore_3: + case Bytecodes::_fstore_3: + case Bytecodes::_dstore_3: + case Bytecodes::_astore_3: + set_local(3, pop()); + break; + case Bytecodes::_istore: + case Bytecodes::_lstore: + case Bytecodes::_fstore: + case Bytecodes::_dstore: + case Bytecodes::_astore: + set_local(iter()->get_index(), pop()); + break; + + case Bytecodes::_bastore: + do_astore(T_BYTE); + break; + case Bytecodes::_castore: + do_astore(T_CHAR); + break; + case Bytecodes::_sastore: + do_astore(T_SHORT); + break; + case Bytecodes::_iastore: + do_astore(T_INT); + break; + case Bytecodes::_lastore: + do_astore(T_LONG); + break; + case Bytecodes::_fastore: + do_astore(T_FLOAT); + break; + case Bytecodes::_dastore: + do_astore(T_DOUBLE); + break; + case Bytecodes::_aastore: + do_astore(T_OBJECT); + break; + + case Bytecodes::_pop: + xpop(); + break; + case Bytecodes::_pop2: + xpop(); + xpop(); + break; + case Bytecodes::_swap: + a = xpop(); + b = xpop(); + xpush(a); + xpush(b); + break; + case Bytecodes::_dup: + a = xpop(); + xpush(a); + xpush(a); + break; + case Bytecodes::_dup_x1: + a = xpop(); + b = xpop(); + xpush(a); + xpush(b); + xpush(a); + break; + case Bytecodes::_dup_x2: + a = xpop(); + b = xpop(); + c = xpop(); + xpush(a); + xpush(c); + xpush(b); + xpush(a); + break; + case Bytecodes::_dup2: + a = xpop(); + b = xpop(); + xpush(b); + xpush(a); + xpush(b); + xpush(a); + break; + case Bytecodes::_dup2_x1: + a = xpop(); + b = xpop(); + c = xpop(); + xpush(b); + xpush(a); + xpush(c); + xpush(b); + xpush(a); + break; + case Bytecodes::_dup2_x2: + a = xpop(); + b = xpop(); + c = xpop(); + d = xpop(); + xpush(b); + xpush(a); + xpush(d); + xpush(c); + xpush(b); + xpush(a); + break; + + case Bytecodes::_arraylength: + do_arraylength(); + break; + + case Bytecodes::_getfield: + do_getfield(); + break; + case Bytecodes::_getstatic: + do_getstatic(); + break; + case Bytecodes::_putfield: + do_putfield(); + break; + case Bytecodes::_putstatic: + do_putstatic(); + break; + + case Bytecodes::_iadd: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateAdd(a->jint_value(), b->jint_value()), false)); + break; + case Bytecodes::_isub: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateSub(a->jint_value(), b->jint_value()), false)); + break; + case Bytecodes::_imul: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateMul(a->jint_value(), b->jint_value()), false)); + break; + case Bytecodes::_idiv: + do_idiv(); + break; + case Bytecodes::_irem: + do_irem(); + break; + case Bytecodes::_ineg: + a = pop(); + push(SharkValue::create_jint( + builder()->CreateNeg(a->jint_value()), a->zero_checked())); + break; + case Bytecodes::_ishl: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateShl( + a->jint_value(), + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x1f))), false)); + break; + case Bytecodes::_ishr: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateAShr( + a->jint_value(), + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x1f))), false)); + break; + case Bytecodes::_iushr: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateLShr( + a->jint_value(), + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x1f))), false)); + break; + case Bytecodes::_iand: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateAnd(a->jint_value(), b->jint_value()), false)); + break; + case Bytecodes::_ior: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateOr(a->jint_value(), b->jint_value()), + a->zero_checked() && b->zero_checked())); + break; + case Bytecodes::_ixor: + b = pop(); + a = pop(); + push(SharkValue::create_jint( + builder()->CreateXor(a->jint_value(), b->jint_value()), false)); + break; + + case Bytecodes::_ladd: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateAdd(a->jlong_value(), b->jlong_value()), false)); + break; + case Bytecodes::_lsub: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateSub(a->jlong_value(), b->jlong_value()), false)); + break; + case Bytecodes::_lmul: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateMul(a->jlong_value(), b->jlong_value()), false)); + break; + case Bytecodes::_ldiv: + do_ldiv(); + break; + case Bytecodes::_lrem: + do_lrem(); + break; + case Bytecodes::_lneg: + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateNeg(a->jlong_value()), a->zero_checked())); + break; + case Bytecodes::_lshl: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateShl( + a->jlong_value(), + builder()->CreateIntCast( + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x3f)), + SharkType::jlong_type(), true)), false)); + break; + case Bytecodes::_lshr: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateAShr( + a->jlong_value(), + builder()->CreateIntCast( + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x3f)), + SharkType::jlong_type(), true)), false)); + break; + case Bytecodes::_lushr: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateLShr( + a->jlong_value(), + builder()->CreateIntCast( + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x3f)), + SharkType::jlong_type(), true)), false)); + break; + case Bytecodes::_land: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateAnd(a->jlong_value(), b->jlong_value()), false)); + break; + case Bytecodes::_lor: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateOr(a->jlong_value(), b->jlong_value()), + a->zero_checked() && b->zero_checked())); + break; + case Bytecodes::_lxor: + b = pop(); + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateXor(a->jlong_value(), b->jlong_value()), false)); + break; + + case Bytecodes::_fadd: + b = pop(); + a = pop(); + push(SharkValue::create_jfloat( + builder()->CreateFAdd(a->jfloat_value(), b->jfloat_value()))); + break; + case Bytecodes::_fsub: + b = pop(); + a = pop(); + push(SharkValue::create_jfloat( + builder()->CreateFSub(a->jfloat_value(), b->jfloat_value()))); + break; + case Bytecodes::_fmul: + b = pop(); + a = pop(); + push(SharkValue::create_jfloat( + builder()->CreateFMul(a->jfloat_value(), b->jfloat_value()))); + break; + case Bytecodes::_fdiv: + b = pop(); + a = pop(); + push(SharkValue::create_jfloat( + builder()->CreateFDiv(a->jfloat_value(), b->jfloat_value()))); + break; + case Bytecodes::_frem: + b = pop(); + a = pop(); + push(SharkValue::create_jfloat( + builder()->CreateFRem(a->jfloat_value(), b->jfloat_value()))); + break; + case Bytecodes::_fneg: + a = pop(); + push(SharkValue::create_jfloat( + builder()->CreateFNeg(a->jfloat_value()))); + break; + + case Bytecodes::_dadd: + b = pop(); + a = pop(); + push(SharkValue::create_jdouble( + builder()->CreateFAdd(a->jdouble_value(), b->jdouble_value()))); + break; + case Bytecodes::_dsub: + b = pop(); + a = pop(); + push(SharkValue::create_jdouble( + builder()->CreateFSub(a->jdouble_value(), b->jdouble_value()))); + break; + case Bytecodes::_dmul: + b = pop(); + a = pop(); + push(SharkValue::create_jdouble( + builder()->CreateFMul(a->jdouble_value(), b->jdouble_value()))); + break; + case Bytecodes::_ddiv: + b = pop(); + a = pop(); + push(SharkValue::create_jdouble( + builder()->CreateFDiv(a->jdouble_value(), b->jdouble_value()))); + break; + case Bytecodes::_drem: + b = pop(); + a = pop(); + push(SharkValue::create_jdouble( + builder()->CreateFRem(a->jdouble_value(), b->jdouble_value()))); + break; + case Bytecodes::_dneg: + a = pop(); + push(SharkValue::create_jdouble( + builder()->CreateFNeg(a->jdouble_value()))); + break; + + case Bytecodes::_iinc: + i = iter()->get_index(); + set_local( + i, + SharkValue::create_jint( + builder()->CreateAdd( + LLVMValue::jint_constant(iter()->get_iinc_con()), + local(i)->jint_value()), false)); + break; + + case Bytecodes::_lcmp: + do_lcmp(); + break; + + case Bytecodes::_fcmpl: + do_fcmp(false, false); + break; + case Bytecodes::_fcmpg: + do_fcmp(false, true); + break; + case Bytecodes::_dcmpl: + do_fcmp(true, false); + break; + case Bytecodes::_dcmpg: + do_fcmp(true, true); + break; + + case Bytecodes::_i2l: + a = pop(); + push(SharkValue::create_jlong( + builder()->CreateIntCast( + a->jint_value(), SharkType::jlong_type(), true), a->zero_checked())); + break; + case Bytecodes::_i2f: + push(SharkValue::create_jfloat( + builder()->CreateSIToFP( + pop()->jint_value(), SharkType::jfloat_type()))); + break; + case Bytecodes::_i2d: + push(SharkValue::create_jdouble( + builder()->CreateSIToFP( + pop()->jint_value(), SharkType::jdouble_type()))); + break; + + case Bytecodes::_l2i: + push(SharkValue::create_jint( + builder()->CreateIntCast( + pop()->jlong_value(), SharkType::jint_type(), true), false)); + break; + case Bytecodes::_l2f: + push(SharkValue::create_jfloat( + builder()->CreateSIToFP( + pop()->jlong_value(), SharkType::jfloat_type()))); + break; + case Bytecodes::_l2d: + push(SharkValue::create_jdouble( + builder()->CreateSIToFP( + pop()->jlong_value(), SharkType::jdouble_type()))); + break; + + case Bytecodes::_f2i: + push(SharkValue::create_jint( + builder()->CreateCall( + builder()->f2i(), pop()->jfloat_value()), false)); + break; + case Bytecodes::_f2l: + push(SharkValue::create_jlong( + builder()->CreateCall( + builder()->f2l(), pop()->jfloat_value()), false)); + break; + case Bytecodes::_f2d: + push(SharkValue::create_jdouble( + builder()->CreateFPExt( + pop()->jfloat_value(), SharkType::jdouble_type()))); + break; + + case Bytecodes::_d2i: + push(SharkValue::create_jint( + builder()->CreateCall( + builder()->d2i(), pop()->jdouble_value()), false)); + break; + case Bytecodes::_d2l: + push(SharkValue::create_jlong( + builder()->CreateCall( + builder()->d2l(), pop()->jdouble_value()), false)); + break; + case Bytecodes::_d2f: + push(SharkValue::create_jfloat( + builder()->CreateFPTrunc( + pop()->jdouble_value(), SharkType::jfloat_type()))); + break; + + case Bytecodes::_i2b: + push(SharkValue::create_jint( + builder()->CreateAShr( + builder()->CreateShl( + pop()->jint_value(), + LLVMValue::jint_constant(24)), + LLVMValue::jint_constant(24)), false)); + break; + case Bytecodes::_i2c: + push(SharkValue::create_jint( + builder()->CreateAnd( + pop()->jint_value(), + LLVMValue::jint_constant(0xffff)), false)); + break; + case Bytecodes::_i2s: + push(SharkValue::create_jint( + builder()->CreateAShr( + builder()->CreateShl( + pop()->jint_value(), + LLVMValue::jint_constant(16)), + LLVMValue::jint_constant(16)), false)); + break; + + case Bytecodes::_return: + do_return(T_VOID); + break; + case Bytecodes::_ireturn: + do_return(T_INT); + break; + case Bytecodes::_lreturn: + do_return(T_LONG); + break; + case Bytecodes::_freturn: + do_return(T_FLOAT); + break; + case Bytecodes::_dreturn: + do_return(T_DOUBLE); + break; + case Bytecodes::_areturn: + do_return(T_OBJECT); + break; + + case Bytecodes::_athrow: + do_athrow(); + break; + + case Bytecodes::_goto: + case Bytecodes::_goto_w: + do_goto(); + break; + + case Bytecodes::_jsr: + case Bytecodes::_jsr_w: + do_jsr(); + break; + + case Bytecodes::_ret: + do_ret(); + break; + + case Bytecodes::_ifnull: + do_if(ICmpInst::ICMP_EQ, SharkValue::null(), pop()); + break; + case Bytecodes::_ifnonnull: + do_if(ICmpInst::ICMP_NE, SharkValue::null(), pop()); + break; + case Bytecodes::_if_acmpeq: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_EQ, b, a); + break; + case Bytecodes::_if_acmpne: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_NE, b, a); + break; + case Bytecodes::_ifeq: + do_if(ICmpInst::ICMP_EQ, SharkValue::jint_constant(0), pop()); + break; + case Bytecodes::_ifne: + do_if(ICmpInst::ICMP_NE, SharkValue::jint_constant(0), pop()); + break; + case Bytecodes::_iflt: + do_if(ICmpInst::ICMP_SLT, SharkValue::jint_constant(0), pop()); + break; + case Bytecodes::_ifle: + do_if(ICmpInst::ICMP_SLE, SharkValue::jint_constant(0), pop()); + break; + case Bytecodes::_ifgt: + do_if(ICmpInst::ICMP_SGT, SharkValue::jint_constant(0), pop()); + break; + case Bytecodes::_ifge: + do_if(ICmpInst::ICMP_SGE, SharkValue::jint_constant(0), pop()); + break; + case Bytecodes::_if_icmpeq: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_EQ, b, a); + break; + case Bytecodes::_if_icmpne: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_NE, b, a); + break; + case Bytecodes::_if_icmplt: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_SLT, b, a); + break; + case Bytecodes::_if_icmple: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_SLE, b, a); + break; + case Bytecodes::_if_icmpgt: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_SGT, b, a); + break; + case Bytecodes::_if_icmpge: + b = pop(); + a = pop(); + do_if(ICmpInst::ICMP_SGE, b, a); + break; + + case Bytecodes::_tableswitch: + case Bytecodes::_lookupswitch: + do_switch(); + break; + + case Bytecodes::_invokestatic: + case Bytecodes::_invokespecial: + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: + do_call(); + break; + + case Bytecodes::_instanceof: + // This is a very common construct: + // + // if (object instanceof Klass) { + // something = (Klass) object; + // ... + // } + // + // which gets compiled to something like this: + // + // 28: aload 9 + // 30: instanceof <Class Klass> + // 33: ifeq 52 + // 36: aload 9 + // 38: checkcast <Class Klass> + // + // Handling both bytecodes at once allows us + // to eliminate the checkcast. + if (iter()->next_bci() < limit && + (iter()->next_bc() == Bytecodes::_ifeq || + iter()->next_bc() == Bytecodes::_ifne) && + (!UseLoopSafepoints || + iter()->next_get_dest() > iter()->next_bci())) { + if (maybe_do_instanceof_if()) { + iter()->next(); + if (SharkTraceBytecodes) + tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc())); + break; + } + } + // fall through + case Bytecodes::_checkcast: + do_instance_check(); + break; + + case Bytecodes::_new: + do_new(); + break; + case Bytecodes::_newarray: + do_newarray(); + break; + case Bytecodes::_anewarray: + do_anewarray(); + break; + case Bytecodes::_multianewarray: + do_multianewarray(); + break; + + case Bytecodes::_monitorenter: + do_monitorenter(); + break; + case Bytecodes::_monitorexit: + do_monitorexit(); + break; + + default: + ShouldNotReachHere(); + } + } +} + +SharkState* SharkBlock::initial_current_state() { + return entry_state()->copy(); +} + +int SharkBlock::switch_default_dest() { + return iter()->get_dest_table(0); +} + +int SharkBlock::switch_table_length() { + switch(bc()) { + case Bytecodes::_tableswitch: + return iter()->get_int_table(2) - iter()->get_int_table(1) + 1; + + case Bytecodes::_lookupswitch: + return iter()->get_int_table(1); + + default: + ShouldNotReachHere(); + } +} + +int SharkBlock::switch_key(int i) { + switch(bc()) { + case Bytecodes::_tableswitch: + return iter()->get_int_table(1) + i; + + case Bytecodes::_lookupswitch: + return iter()->get_int_table(2 + 2 * i); + + default: + ShouldNotReachHere(); + } +} + +int SharkBlock::switch_dest(int i) { + switch(bc()) { + case Bytecodes::_tableswitch: + return iter()->get_dest_table(i + 3); + + case Bytecodes::_lookupswitch: + return iter()->get_dest_table(2 + 2 * i + 1); + + default: + ShouldNotReachHere(); + } +} + +void SharkBlock::do_div_or_rem(bool is_long, bool is_rem) { + SharkValue *sb = pop(); + SharkValue *sa = pop(); + + check_divide_by_zero(sb); + + Value *a, *b, *p, *q; + if (is_long) { + a = sa->jlong_value(); + b = sb->jlong_value(); + p = LLVMValue::jlong_constant(0x8000000000000000LL); + q = LLVMValue::jlong_constant(-1); + } + else { + a = sa->jint_value(); + b = sb->jint_value(); + p = LLVMValue::jint_constant(0x80000000); + q = LLVMValue::jint_constant(-1); + } + + BasicBlock *ip = builder()->GetBlockInsertionPoint(); + BasicBlock *special_case = builder()->CreateBlock(ip, "special_case"); + BasicBlock *general_case = builder()->CreateBlock(ip, "general_case"); + BasicBlock *done = builder()->CreateBlock(ip, "done"); + + builder()->CreateCondBr( + builder()->CreateAnd( + builder()->CreateICmpEQ(a, p), + builder()->CreateICmpEQ(b, q)), + special_case, general_case); + + builder()->SetInsertPoint(special_case); + Value *special_result; + if (is_rem) { + if (is_long) + special_result = LLVMValue::jlong_constant(0); + else + special_result = LLVMValue::jint_constant(0); + } + else { + special_result = a; + } + builder()->CreateBr(done); + + builder()->SetInsertPoint(general_case); + Value *general_result; + if (is_rem) + general_result = builder()->CreateSRem(a, b); + else + general_result = builder()->CreateSDiv(a, b); + builder()->CreateBr(done); + + builder()->SetInsertPoint(done); + PHINode *result; + if (is_long) + result = builder()->CreatePHI(SharkType::jlong_type(), "result"); + else + result = builder()->CreatePHI(SharkType::jint_type(), "result"); + result->addIncoming(special_result, special_case); + result->addIncoming(general_result, general_case); + + if (is_long) + push(SharkValue::create_jlong(result, false)); + else + push(SharkValue::create_jint(result, false)); +} + +void SharkBlock::do_field_access(bool is_get, bool is_field) { + bool will_link; + ciField *field = iter()->get_field(will_link); + assert(will_link, "typeflow responsibility"); + assert(is_field != field->is_static(), "mismatch"); + + // Pop the value off the stack where necessary + SharkValue *value = NULL; + if (!is_get) + value = pop(); + + // Find the object we're accessing, if necessary + Value *object = NULL; + if (is_field) { + SharkValue *value = pop(); + check_null(value); + object = value->generic_value(); + } + if (is_get && field->is_constant()) { + SharkConstant *constant = SharkConstant::for_field(iter()); + if (constant->is_loaded()) + value = constant->value(builder()); + } + if (!is_get || value == NULL) { + if (!is_field) + object = builder()->CreateInlineOop(field->holder()); + + BasicType basic_type = field->type()->basic_type(); + const Type *stack_type = SharkType::to_stackType(basic_type); + const Type *field_type = SharkType::to_arrayType(basic_type); + + Value *addr = builder()->CreateAddressOfStructEntry( + object, in_ByteSize(field->offset_in_bytes()), + PointerType::getUnqual(field_type), + "addr"); + + // Do the access + if (is_get) { + Value *field_value = builder()->CreateLoad(addr); + + if (field_type != stack_type) { + field_value = builder()->CreateIntCast( + field_value, stack_type, basic_type != T_CHAR); + } + + value = SharkValue::create_generic(field->type(), field_value, false); + } + else { + Value *field_value = value->generic_value(); + + if (field_type != stack_type) { + field_value = builder()->CreateIntCast( + field_value, field_type, basic_type != T_CHAR); + } + + builder()->CreateStore(field_value, addr); + + if (!field->type()->is_primitive_type()) + builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr); + + if (field->is_volatile()) + builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD); + } + } + + // Push the value onto the stack where necessary + if (is_get) + push(value); +} + +void SharkBlock::do_lcmp() { + Value *b = pop()->jlong_value(); + Value *a = pop()->jlong_value(); + + BasicBlock *ip = builder()->GetBlockInsertionPoint(); + BasicBlock *ne = builder()->CreateBlock(ip, "lcmp_ne"); + BasicBlock *lt = builder()->CreateBlock(ip, "lcmp_lt"); + BasicBlock *gt = builder()->CreateBlock(ip, "lcmp_gt"); + BasicBlock *done = builder()->CreateBlock(ip, "done"); + + BasicBlock *eq = builder()->GetInsertBlock(); + builder()->CreateCondBr(builder()->CreateICmpEQ(a, b), done, ne); + + builder()->SetInsertPoint(ne); + builder()->CreateCondBr(builder()->CreateICmpSLT(a, b), lt, gt); + + builder()->SetInsertPoint(lt); + builder()->CreateBr(done); + + builder()->SetInsertPoint(gt); + builder()->CreateBr(done); + + builder()->SetInsertPoint(done); + PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result"); + result->addIncoming(LLVMValue::jint_constant(-1), lt); + result->addIncoming(LLVMValue::jint_constant(0), eq); + result->addIncoming(LLVMValue::jint_constant(1), gt); + + push(SharkValue::create_jint(result, false)); +} + +void SharkBlock::do_fcmp(bool is_double, bool unordered_is_greater) { + Value *a, *b; + if (is_double) { + b = pop()->jdouble_value(); + a = pop()->jdouble_value(); + } + else { + b = pop()->jfloat_value(); + a = pop()->jfloat_value(); + } + + BasicBlock *ip = builder()->GetBlockInsertionPoint(); + BasicBlock *ordered = builder()->CreateBlock(ip, "ordered"); + BasicBlock *ge = builder()->CreateBlock(ip, "fcmp_ge"); + BasicBlock *lt = builder()->CreateBlock(ip, "fcmp_lt"); + BasicBlock *eq = builder()->CreateBlock(ip, "fcmp_eq"); + BasicBlock *gt = builder()->CreateBlock(ip, "fcmp_gt"); + BasicBlock *done = builder()->CreateBlock(ip, "done"); + + builder()->CreateCondBr( + builder()->CreateFCmpUNO(a, b), + unordered_is_greater ? gt : lt, ordered); + + builder()->SetInsertPoint(ordered); + builder()->CreateCondBr(builder()->CreateFCmpULT(a, b), lt, ge); + + builder()->SetInsertPoint(ge); + builder()->CreateCondBr(builder()->CreateFCmpUGT(a, b), gt, eq); + + builder()->SetInsertPoint(lt); + builder()->CreateBr(done); + + builder()->SetInsertPoint(gt); + builder()->CreateBr(done); + + builder()->SetInsertPoint(eq); + builder()->CreateBr(done); + + builder()->SetInsertPoint(done); + PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result"); + result->addIncoming(LLVMValue::jint_constant(-1), lt); + result->addIncoming(LLVMValue::jint_constant(0), eq); + result->addIncoming(LLVMValue::jint_constant(1), gt); + + push(SharkValue::create_jint(result, false)); +} + +void SharkBlock::emit_IR() { + ShouldNotCallThis(); +} + +SharkState* SharkBlock::entry_state() { + ShouldNotCallThis(); +} + +void SharkBlock::do_zero_check(SharkValue* value) { + ShouldNotCallThis(); +} + +void SharkBlock::maybe_add_backedge_safepoint() { + ShouldNotCallThis(); +} + +bool SharkBlock::has_trap() { + return false; +} + +int SharkBlock::trap_request() { + ShouldNotCallThis(); +} + +int SharkBlock::trap_bci() { + ShouldNotCallThis(); +} + +void SharkBlock::do_trap(int trap_request) { + ShouldNotCallThis(); +} + +void SharkBlock::do_arraylength() { + ShouldNotCallThis(); +} + +void SharkBlock::do_aload(BasicType basic_type) { + ShouldNotCallThis(); +} + +void SharkBlock::do_astore(BasicType basic_type) { + ShouldNotCallThis(); +} + +void SharkBlock::do_return(BasicType type) { + ShouldNotCallThis(); +} + +void SharkBlock::do_athrow() { + ShouldNotCallThis(); +} + +void SharkBlock::do_goto() { + ShouldNotCallThis(); +} + +void SharkBlock::do_jsr() { + ShouldNotCallThis(); +} + +void SharkBlock::do_ret() { + ShouldNotCallThis(); +} + +void SharkBlock::do_if(ICmpInst::Predicate p, SharkValue* b, SharkValue* a) { + ShouldNotCallThis(); +} + +void SharkBlock::do_switch() { + ShouldNotCallThis(); +} + +void SharkBlock::do_call() { + ShouldNotCallThis(); +} + +void SharkBlock::do_instance_check() { + ShouldNotCallThis(); +} + +bool SharkBlock::maybe_do_instanceof_if() { + ShouldNotCallThis(); +} + +void SharkBlock::do_new() { + ShouldNotCallThis(); +} + +void SharkBlock::do_newarray() { + ShouldNotCallThis(); +} + +void SharkBlock::do_anewarray() { + ShouldNotCallThis(); +} + +void SharkBlock::do_multianewarray() { + ShouldNotCallThis(); +} + +void SharkBlock::do_monitorenter() { + ShouldNotCallThis(); +} + +void SharkBlock::do_monitorexit() { + ShouldNotCallThis(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/shark/sharkBlock.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,281 @@ +/* + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +class SharkState; + +class SharkBlock : public SharkTargetInvariants { + protected: + SharkBlock(const SharkTargetInvariants* parent) + : SharkTargetInvariants(parent), + _iter(target()), + _current_state(NULL) {} + + SharkBlock(const SharkCompileInvariants* parent, ciMethod* target) + : SharkTargetInvariants(parent, target), + _iter(target), + _current_state(NULL) {} + + private: + ciBytecodeStream _iter; + SharkState* _current_state; + + public: + ciBytecodeStream* iter() { + return &_iter; + } + Bytecodes::Code bc() { + return iter()->cur_bc(); + } + int bci() { + return iter()->cur_bci(); + } + + // Entry state + protected: + virtual SharkState* entry_state(); + + // Current state + private: + SharkState* initial_current_state(); + + public: + SharkState* current_state() { + if (_current_state == NULL) + set_current_state(initial_current_state()); + return _current_state; + } + + protected: + void set_current_state(SharkState* current_state) { + _current_state = current_state; + } + + // Local variables + protected: + SharkValue* local(int index) { + SharkValue *value = current_state()->local(index); + assert(value != NULL, "shouldn't be"); + assert(value->is_one_word() || + (index + 1 < max_locals() && + current_state()->local(index + 1) == NULL), "should be"); + return value; + } + void set_local(int index, SharkValue* value) { + assert(value != NULL, "shouldn't be"); + current_state()->set_local(index, value); + if (value->is_two_word()) + current_state()->set_local(index + 1, NULL); + } + + // Expression stack (raw) + protected: + void xpush(SharkValue* value) { + current_state()->push(value); + } + SharkValue* xpop() { + return current_state()->pop(); + } + SharkValue* xstack(int slot) { + SharkValue *value = current_state()->stack(slot); + assert(value != NULL, "shouldn't be"); + assert(value->is_one_word() || + (slot > 0 && + current_state()->stack(slot - 1) == NULL), "should be"); + return value; + } + int xstack_depth() { + return current_state()->stack_depth(); + } + + // Expression stack (cooked) + protected: + void push(SharkValue* value) { + assert(value != NULL, "shouldn't be"); + xpush(value); + if (value->is_two_word()) + xpush(NULL); + } + SharkValue* pop() { + int size = current_state()->stack(0) == NULL ? 2 : 1; + if (size == 2) + xpop(); + SharkValue *value = xpop(); + assert(value && value->size() == size, "should be"); + return value; + } + SharkValue* pop_result(BasicType type) { + SharkValue *result = pop(); + +#ifdef ASSERT + switch (result->basic_type()) { + case T_BOOLEAN: + case T_BYTE: + case T_CHAR: + case T_SHORT: + assert(type == T_INT, "type mismatch"); + break; + + case T_ARRAY: + assert(type == T_OBJECT, "type mismatch"); + break; + + default: + assert(result->basic_type() == type, "type mismatch"); + } +#endif // ASSERT + + return result; + } + + // Code generation + public: + virtual void emit_IR(); + + protected: + void parse_bytecode(int start, int limit); + + // Helpers + protected: + virtual void do_zero_check(SharkValue* value); + + // Zero checking + protected: + void check_null(SharkValue* object) { + zero_check(object); + } + void check_divide_by_zero(SharkValue* value) { + zero_check(value); + } + private: + void zero_check(SharkValue* value) { + if (!value->zero_checked()) + do_zero_check(value); + } + + // Safepoints + protected: + virtual void maybe_add_backedge_safepoint(); + + // Traps + protected: + virtual bool has_trap(); + virtual int trap_request(); + virtual int trap_bci(); + virtual void do_trap(int trap_request); + + // arraylength + protected: + virtual void do_arraylength(); + + // *aload and *astore + protected: + virtual void do_aload(BasicType basic_type); + virtual void do_astore(BasicType basic_type); + + // *div and *rem + private: + void do_idiv() { + do_div_or_rem(false, false); + } + void do_irem() { + do_div_or_rem(false, true); + } + void do_ldiv() { + do_div_or_rem(true, false); + } + void do_lrem() { + do_div_or_rem(true, true); + } + void do_div_or_rem(bool is_long, bool is_rem); + + // get* and put* + private: + void do_getstatic() { + do_field_access(true, false); + } + void do_getfield() { + do_field_access(true, true); + } + void do_putstatic() { + do_field_access(false, false); + } + void do_putfield() { + do_field_access(false, true); + } + void do_field_access(bool is_get, bool is_field); + + // lcmp and [fd]cmp[lg] + private: + void do_lcmp(); + void do_fcmp(bool is_double, bool unordered_is_greater); + + // *return and athrow + protected: + virtual void do_return(BasicType type); + virtual void do_athrow(); + + // goto* + protected: + virtual void do_goto(); + + // jsr* and ret + protected: + virtual void do_jsr(); + virtual void do_ret(); + + // if* + protected: + virtual void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a); + + // *switch + protected: + int switch_default_dest(); + int switch_table_length(); + int switch_key(int i); + int switch_dest(int i); + + virtual void do_switch(); + + // invoke* + protected: + virtual void do_call(); + + // checkcast and instanceof + protected: + virtual void do_instance_check(); + virtual bool maybe_do_instanceof_if(); + + // new and *newarray + protected: + virtual void do_new(); + virtual void do_newarray(); + virtual void do_anewarray(); + virtual void do_multianewarray(); + + // monitorenter and monitorexit + protected: + virtual void do_monitorenter(); + virtual void do_monitorexit(); +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/shark/sharkBuilder.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,591 @@ +/* + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009, 2010 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_sharkBuilder.cpp.incl" + +using namespace llvm; + +SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer) + : IRBuilder<>(SharkContext::current()), + _code_buffer(code_buffer) { +} + +// Helpers for accessing structures +Value* SharkBuilder::CreateAddressOfStructEntry(Value* base, + ByteSize offset, + const Type* type, + const char* name) { + return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name); +} + +LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base, + ByteSize offset, + const Type* type, + const char* name) { + return CreateLoad( + CreateAddressOfStructEntry( + base, offset, PointerType::getUnqual(type)), + name); +} + +// Helpers for accessing arrays + +LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) { + return CreateValueOfStructEntry( + arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()), + SharkType::jint_type(), "length"); +} + +Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, + const Type* element_type, + int element_bytes, + ByteSize base_offset, + Value* index, + const char* name) { + Value* offset = CreateIntCast(index, SharkType::intptr_type(), false); + if (element_bytes != 1) + offset = CreateShl( + offset, + LLVMValue::intptr_constant(exact_log2(element_bytes))); + offset = CreateAdd( + LLVMValue::intptr_constant(in_bytes(base_offset)), offset); + + return CreateIntToPtr( + CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset), + PointerType::getUnqual(element_type), + name); +} + +Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, + BasicType basic_type, + ByteSize base_offset, + Value* index, + const char* name) { + return CreateArrayAddress( + arrayoop, + SharkType::to_arrayType(basic_type), + type2aelembytes(basic_type), + base_offset, index, name); +} + +Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, + BasicType basic_type, + Value* index, + const char* name) { + return CreateArrayAddress( + arrayoop, basic_type, + in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)), + index, name); +} + +// Helpers for creating intrinsics and external functions. + +const Type* SharkBuilder::make_type(char type, bool void_ok) { + switch (type) { + // Primitive types + case 'c': + return SharkType::jbyte_type(); + case 'i': + return SharkType::jint_type(); + case 'l': + return SharkType::jlong_type(); + case 'x': + return SharkType::intptr_type(); + case 'f': + return SharkType::jfloat_type(); + case 'd': + return SharkType::jdouble_type(); + + // Pointers to primitive types + case 'C': + case 'I': + case 'L': + case 'X': + case 'F': + case 'D': + return PointerType::getUnqual(make_type(tolower(type), false)); + + // VM objects + case 'T': + return SharkType::thread_type(); + case 'M': + return PointerType::getUnqual(SharkType::monitor_type()); + case 'O': + return SharkType::oop_type(); + + // Miscellaneous + case 'v': + assert(void_ok, "should be"); + return SharkType::void_type(); + case '1': + return SharkType::bit_type(); + + default: + ShouldNotReachHere(); + } +} + +const FunctionType* SharkBuilder::make_ftype(const char* params, + const char* ret) { + std::vector<const Type*> param_types; + for (const char* c = params; *c; c++) + param_types.push_back(make_type(*c, false)); + + assert(strlen(ret) == 1, "should be"); + const Type *return_type = make_type(*ret, true); + + return FunctionType::get(return_type, param_types, false); +} + +// Create an object representing an intrinsic or external function by +// referencing the symbol by name. This is the LLVM-style approach, +// but it cannot be used on functions within libjvm.so its symbols +// are not exported. Note that you cannot make this work simply by +// exporting the symbols, as some symbols have the same names as +// symbols in the standard libraries (eg, atan2, fabs) and would +// obscure them were they visible. +Value* SharkBuilder::make_function(const char* name, + const char* params, + const char* ret) { + return SharkContext::current().get_external(name, make_ftype(params, ret)); +} + +// Create an object representing an external function by inlining a +// function pointer in the code. This is not the LLVM way, but it's +// the only way to access functions in libjvm.so and functions like +// __kernel_dmb on ARM which is accessed via an absolute address. +Value* SharkBuilder::make_function(address func, + const char* params, + const char* ret) { + return CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) func), + PointerType::getUnqual(make_ftype(params, ret))); +} + +// VM calls + +Value* SharkBuilder::find_exception_handler() { + return make_function( + (address) SharkRuntime::find_exception_handler, "TIi", "i"); +} + +Value* SharkBuilder::monitorenter() { + return make_function((address) SharkRuntime::monitorenter, "TM", "v"); +} + +Value* SharkBuilder::monitorexit() { + return make_function((address) SharkRuntime::monitorexit, "TM", "v"); +} + +Value* SharkBuilder::new_instance() { + return make_function((address) SharkRuntime::new_instance, "Ti", "v"); +} + +Value* SharkBuilder::newarray() { + return make_function((address) SharkRuntime::newarray, "Tii", "v"); +} + +Value* SharkBuilder::anewarray() { + return make_function((address) SharkRuntime::anewarray, "Tii", "v"); +} + +Value* SharkBuilder::multianewarray() { + return make_function((address) SharkRuntime::multianewarray, "TiiI", "v"); +} + +Value* SharkBuilder::register_finalizer() { + return make_function((address) SharkRuntime::register_finalizer, "TO", "v"); +} + +Value* SharkBuilder::safepoint() { + return make_function((address) SafepointSynchronize::block, "T", "v"); +} + +Value* SharkBuilder::throw_ArithmeticException() { + return make_function( + (address) SharkRuntime::throw_ArithmeticException, "TCi", "v"); +} + +Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() { + return make_function( + (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v"); +} + +Value* SharkBuilder::throw_ClassCastException() { + return make_function( + (address) SharkRuntime::throw_ClassCastException, "TCi", "v"); +} + +Value* SharkBuilder::throw_NullPointerException() { + return make_function( + (address) SharkRuntime::throw_NullPointerException, "TCi", "v"); +} + +// High-level non-VM calls + +Value* SharkBuilder::f2i() { + return make_function((address) SharedRuntime::f2i, "f", "i"); +} + +Value* SharkBuilder::f2l() { + return make_function((address) SharedRuntime::f2l, "f", "l"); +} + +Value* SharkBuilder::d2i() { + return make_function((address) SharedRuntime::d2i, "d", "i"); +} + +Value* SharkBuilder::d2l() { + return make_function((address) SharedRuntime::d2l, "d", "l"); +} + +Value* SharkBuilder::is_subtype_of() { + return make_function((address) SharkRuntime::is_subtype_of, "OO", "c"); +} + +Value* SharkBuilder::current_time_millis() { + return make_function((address) os::javaTimeMillis, "", "l"); +} + +Value* SharkBuilder::sin() { + return make_function("llvm.sin.f64", "d", "d"); +} + +Value* SharkBuilder::cos() { + return make_function("llvm.cos.f64", "d", "d"); +} + +Value* SharkBuilder::tan() { + return make_function((address) ::tan, "d", "d"); +} + +Value* SharkBuilder::atan2() { + return make_function((address) ::atan2, "dd", "d"); +} + +Value* SharkBuilder::sqrt() { + return make_function("llvm.sqrt.f64", "d", "d"); +} + +Value* SharkBuilder::log() { + return make_function("llvm.log.f64", "d", "d"); +} + +Value* SharkBuilder::log10() { + return make_function("llvm.log10.f64", "d", "d"); +} + +Value* SharkBuilder::pow() { + return make_function("llvm.pow.f64", "dd", "d"); +} + +Value* SharkBuilder::exp() { + return make_function("llvm.exp.f64", "d", "d"); +} + +Value* SharkBuilder::fabs() { + return make_function((address) ::fabs, "d", "d"); +} + +Value* SharkBuilder::unsafe_field_offset_to_byte_offset() { + extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); + return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l"); +} + +Value* SharkBuilder::osr_migration_end() { + return make_function((address) SharedRuntime::OSR_migration_end, "C", "v"); +} + +// Semi-VM calls + +Value* SharkBuilder::throw_StackOverflowError() { + return make_function((address) ZeroStack::handle_overflow, "T", "v"); +} + +Value* SharkBuilder::uncommon_trap() { + return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i"); +} + +Value* SharkBuilder::deoptimized_entry_point() { + return make_function((address) CppInterpreter::main_loop, "iT", "v"); +} + +// Native-Java transition + +Value* SharkBuilder::check_special_condition_for_native_trans() { + return make_function( + (address) JavaThread::check_special_condition_for_native_trans, + "T", "v"); +} + +// Low-level non-VM calls + +// The ARM-specific code here is to work around unimplemented +// atomic exchange and memory barrier intrinsics in LLVM. +// +// Delegating to external functions for these would normally +// incur a speed penalty, but Linux on ARM is a special case +// in that atomic operations on that platform are handled by +// external functions anyway. It would be *preferable* for +// the calls to be hidden away in LLVM, but it's not hurting +// performance so having the calls here is acceptable. +// +// If you are building Shark on a platform without atomic +// exchange and/or memory barrier intrinsics then it is only +// acceptable to mimic this approach if your platform cannot +// perform these operations without delegating to a function. + +#ifdef ARM +static jint zero_cmpxchg_int(volatile jint *ptr, jint oldval, jint newval) { + return Atomic::cmpxchg(newval, ptr, oldval); +} +#endif // ARM + +Value* SharkBuilder::cmpxchg_int() { + return make_function( +#ifdef ARM + (address) zero_cmpxchg_int, +#else + "llvm.atomic.cmp.swap.i32.p0i32", +#endif // ARM + "Iii", "i"); +} + +#ifdef ARM +static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr, + intptr_t oldval, + intptr_t newval) { + return Atomic::cmpxchg_ptr(newval, ptr, oldval); +} +#endif // ARM + +Value* SharkBuilder::cmpxchg_ptr() { + return make_function( +#ifdef ARM + (address) zero_cmpxchg_ptr, +#else + "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32") ".p0i" LP64_ONLY("64") NOT_LP64("32"), +#endif // ARM + "Xxx", "x"); +} + +Value* SharkBuilder::frame_address() { + return make_function("llvm.frameaddress", "i", "C"); +} + +Value* SharkBuilder::memory_barrier() { + return make_function( +#ifdef ARM + (address) 0xffff0fa0, // __kernel_dmb +#else + "llvm.memory.barrier", +#endif // ARM + "11111", "v"); +} + +Value* SharkBuilder::memset() { +#if SHARK_LLVM_VERSION >= 28 + // LLVM 2.8 added a fifth isVolatile field for memset + // introduced with LLVM r100304 + return make_function("llvm.memset.i32", "Cciii", "v"); +#else + return make_function("llvm.memset.i32", "Ccii", "v"); +#endif +} + +Value* SharkBuilder::unimplemented() { + return make_function((address) report_unimplemented, "Ci", "v"); +} + +Value* SharkBuilder::should_not_reach_here() { + return make_function((address) report_should_not_reach_here, "Ci", "v"); +} + +Value* SharkBuilder::dump() { + return make_function((address) SharkRuntime::dump, "Cx", "v"); +} + +// Public interface to low-level non-VM calls + +CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value, + Value* dst, + Value* compare_value) { + return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value); +} + +CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value, + Value* dst, + Value* compare_value) { + return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value); +} + +CallInst* SharkBuilder::CreateGetFrameAddress() { + return CreateCall(frame_address(), LLVMValue::jint_constant(0)); +} + +CallInst *SharkBuilder::CreateMemoryBarrier(int flags) { + Value *args[] = { + LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0), + LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0), + LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0), + LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0), + LLVMValue::bit_constant(1)}; + + return CreateCall(memory_barrier(), args, args + 5); +} + +CallInst* SharkBuilder::CreateMemset(Value* dst, + Value* value, + Value* len, + Value* align) { +#if SHARK_LLVM_VERSION >= 28 + return CreateCall5(memset(), dst, value, len, align, + LLVMValue::jint_constant(0)); +#else + return CreateCall4(memset(), dst, value, len, align); +#endif +} + +CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) { + return CreateCall2( + unimplemented(), + CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) file), + PointerType::getUnqual(SharkType::jbyte_type())), + LLVMValue::jint_constant(line)); +} + +CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) { + return CreateCall2( + should_not_reach_here(), + CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) file), + PointerType::getUnqual(SharkType::jbyte_type())), + LLVMValue::jint_constant(line)); +} + +#ifndef PRODUCT +CallInst* SharkBuilder::CreateDump(Value* value) { + const char *name; + if (value->hasName()) + // XXX this leaks, but it's only debug code + name = strdup(value->getName().str().c_str()); + else + name = "unnamed_value"; + + if (isa<PointerType>(value->getType())) + value = CreatePtrToInt(value, SharkType::intptr_type()); + else if (value->getType()-> +#if SHARK_LLVM_VERSION >= 27 + isIntegerTy() +#else + isInteger() +#endif + ) + value = CreateIntCast(value, SharkType::intptr_type(), false); + else + Unimplemented(); + + return CreateCall2( + dump(), + CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) name), + PointerType::getUnqual(SharkType::jbyte_type())), + value); +} +#endif // PRODUCT + +// HotSpot memory barriers + +void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) { + if (bs->kind() != BarrierSet::CardTableModRef) + Unimplemented(); + + CreateStore( + LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card), + CreateIntToPtr( + CreateAdd( + LLVMValue::intptr_constant( + (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base), + CreateLShr( + CreatePtrToInt(field, SharkType::intptr_type()), + LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), + PointerType::getUnqual(SharkType::jbyte_type()))); +} + +// Helpers for accessing the code buffer + +Value* SharkBuilder::code_buffer_address(int offset) { + return CreateAdd( + code_buffer()->base_pc(), + LLVMValue::intptr_constant(offset)); +} + +Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) { + return CreateLoad( + CreateIntToPtr( + code_buffer_address(code_buffer()->inline_oop(object)), + PointerType::getUnqual(SharkType::oop_type())), + name); +} + +Value* SharkBuilder::CreateInlineData(void* data, + size_t size, + const Type* type, + const char* name) { + return CreateIntToPtr( + code_buffer_address(code_buffer()->inline_data(data, size)), + type, + name); +} + +// Helpers for creating basic blocks. + +BasicBlock* SharkBuilder::GetBlockInsertionPoint() const { + BasicBlock *cur = GetInsertBlock(); + + // BasicBlock::Create takes an insertBefore argument, so + // we need to find the block _after_ the current block + Function::iterator iter = cur->getParent()->begin(); + Function::iterator end = cur->getParent()->end(); + while (iter != end) { + iter++; + if (&*iter == cur) { + iter++; + break; + } + } + + if (iter == end) + return NULL; + else + return iter; +} + +BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const { + return BasicBlock::Create( + SharkContext::current(), name, GetInsertBlock()->getParent(), ip); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/shark/sharkBuilder.hpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009, 2010 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +class SharkBuilder : public llvm::IRBuilder<> { + friend class SharkCompileInvariants; + + public: + SharkBuilder(SharkCodeBuffer* code_buffer); + + // The code buffer we are building into. + private: + SharkCodeBuffer* _code_buffer; + + protected: + SharkCodeBuffer* code_buffer() const { + return _code_buffer; + } + + // Helpers for accessing structures. + public: + llvm::Value* CreateAddressOfStructEntry(llvm::Value* base, + ByteSize offset, + const llvm::Type* type, + const char *name = ""); + llvm::LoadInst* CreateValueOfStructEntry(llvm::Value* base, + ByteSize offset, + const llvm::Type* type, + const char *name = ""); + + // Helpers for accessing arrays. + public: + llvm::LoadInst* CreateArrayLength(llvm::Value* arrayoop); + llvm::Value* CreateArrayAddress(llvm::Value* arrayoop, + const llvm::Type* element_type, + int element_bytes, + ByteSize base_offset, + llvm::Value* index, + const char* name = ""); + llvm::Value* CreateArrayAddress(llvm::Value* arrayoop, + BasicType basic_type, + ByteSize base_offset, + llvm::Value* index, + const char* name = ""); + llvm::Value* CreateArrayAddress(llvm::Value* arrayoop, + BasicType basic_type, + llvm::Value* index, + const char* name = ""); + + // Helpers for creating intrinsics and external functions. + private: + static const llvm::Type* make_type(char type, bool void_ok); + static const llvm::FunctionType* make_ftype(const char* params, + const char* ret); + llvm::Value* make_function(const char* name, + const char* params, + const char* ret); + llvm::Value* make_function(address func, + const char* params, + const char* ret); + + // Intrinsics and external functions, part 1: VM calls. + // These are functions declared with JRT_ENTRY and JRT_EXIT, + // macros which flip the thread from _thread_in_Java to + // _thread_in_vm and back. VM calls always safepoint, and can + // therefore throw exceptions. VM calls require of setup and + // teardown, and must be called with SharkTopLevelBlock::call_vm. + public: + llvm::Value* find_exception_handler(); + llvm::Value* monitorenter(); + llvm::Value* monitorexit(); + llvm::Value* new_instance(); + llvm::Value* newarray(); + llvm::Value* anewarray(); + llvm::Value* multianewarray(); + llvm::Value* register_finalizer(); + llvm::Value* safepoint(); + llvm::Value* throw_ArithmeticException(); + llvm::Value* throw_ArrayIndexOutOfBoundsException(); + llvm::Value* throw_ClassCastException(); + llvm::Value* throw_NullPointerException(); + + // Intrinsics and external functions, part 2: High-level non-VM calls. + // These are called like normal functions. The stack is not set + // up for walking so they must not safepoint or throw exceptions, + // or call anything that might. + public: + llvm::Value* f2i(); + llvm::Value* f2l(); + llvm::Value* d2i(); + llvm::Value* d2l(); + llvm::Value* is_subtype_of(); + llvm::Value* current_time_millis(); + llvm::Value* sin(); + llvm::Value* cos(); + llvm::Value* tan(); + llvm::Value* atan2(); + llvm::Value* sqrt(); + llvm::Value* log(); + llvm::Value* log10(); + llvm::Value* pow(); + llvm::Value* exp(); + llvm::Value* fabs(); + llvm::Value* unsafe_field_offset_to_byte_offset(); + llvm::Value* osr_migration_end(); + + // Intrinsics and external functions, part 3: semi-VM calls. + // These are special cases that do VM call stuff but are invoked + // as though they were normal calls. This is acceptable so long + // as the method that calls them returns to its immediately that + // the semi VM call returns. + public: + llvm::Value* throw_StackOverflowError(); + llvm::Value* uncommon_trap(); + llvm::Value* deoptimized_entry_point(); + + // Intrinsics and external functions, part 4: Native-Java transition. + // This is a special case in that it is invoked during a thread + // state transition. The stack must be set up for walking, and it + // may throw exceptions, but the state is _thread_in_native_trans. + public: + llvm::Value* check_special_condition_for_native_trans(); + + // Intrinsics and external functions, part 5: Low-level non-VM calls. + // These have the same caveats as the high-level non-VM calls + // above. They are not accessed directly; rather, you should + // access them via the various Create* methods below. + private: + llvm::Value* cmpxchg_int(); + llvm::Value* cmpxchg_ptr(); + llvm::Value* frame_address(); + llvm::Value* memory_barrier(); + llvm::Value* memset(); + llvm::Value* unimplemented(); + llvm::Value* should_not_reach_here(); + llvm::Value* dump(); + + // Public interface to low-level non-VM calls. + public: + llvm::CallInst* CreateCmpxchgInt(llvm::Value* exchange_value, + llvm::Value* dst, + llvm::Value* compare_value); + llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value, + llvm::Value* dst, + llvm::Value* compare_value); + llvm::CallInst* CreateGetFrameAddress(); + llvm::CallInst* CreateMemoryBarrier(int flags); + llvm::CallInst* CreateMemset(llvm::Value* dst, + llvm::Value* value, + llvm::Value* len, + llvm::Value* align); + llvm::CallInst* CreateUnimplemented(const char* file, int line); + llvm::CallInst* CreateShouldNotReachHere(const char* file, int line); + NOT_PRODUCT(llvm::CallInst* CreateDump(llvm::Value* value)); + + // Flags for CreateMemoryBarrier. + public: + enum BarrierFlags { + BARRIER_LOADLOAD = 1, + BARRIER_LOADSTORE = 2, + BARRIER_STORELOAD = 4, + BARRIER_STORESTORE = 8 + }; + + // HotSpot memory barriers + public: + void CreateUpdateBarrierSet(BarrierSet* bs, llvm::Value* field); + + // Helpers for accessing the code buffer. + public: + llvm::Value* code_buffer_address(int offset); + llvm::Value* CreateInlineOop(jobject object, const char* name = ""); + llvm::Value* CreateInlineOop(ciObject* object, const char* name = "") { + return CreateInlineOop(object->constant_encoding(), name); + } + llvm::Value* CreateInlineData(void* data, + size_t size, + const llvm::Type* type, + const char* name = ""); + + // Helpers for creating basic blocks. + // NB don't use unless SharkFunction::CreateBlock is unavailable. + // XXX these are hacky and should be removed. + public: + llvm::BasicBlock* GetBlockInsertionPoint() const; + llvm::BasicBlock* CreateBlock(llvm::BasicBlock* ip, + const char* name="") const; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Thu Sep 02 22:11:05 2010 -0700 @@ -0,0 +1,259 @@ +/* + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_sharkCacheDecache.cpp.incl" + +using namespace llvm; + +void SharkDecacher::start_frame() { + // Start recording the debug information + _pc_offset = code_buffer()->create_unique_offset(); + _oopmap = new OopMap( + oopmap_slot_munge(stack()->oopmap_frame_size()), + oopmap_slot_munge(arg_size())); + debug_info()->add_safepoint(pc_offset(), oopmap()); +} + +void SharkDecacher::start_stack(int stack_depth) { + // Create the array we'll record our stack slots in + _exparray = new GrowableArray<ScopeValue*>(stack_depth); + + // Set the stack pointer + stack()->CreateStoreStackPointer( + builder()->CreatePtrToInt( + stack()->slot_addr( + stack()->stack_slot