OpenJDK / amber / amber
changeset 6786:08f72406f403
Merge
author | herrick |
---|---|
date | Fri, 20 Aug 2010 14:48:10 -0400 |
parents | 8c33458fc946 439de530aac5 |
children | 648846ff9d14 |
files | jdk/test/java/net/Socket/AccurateTimeout.java |
diffstat | 969 files changed, 35978 insertions(+), 3447 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Thu Aug 12 23:21:17 2010 -0700 +++ b/.hgtags Fri Aug 20 14:48:10 2010 -0400 @@ -77,3 +77,7 @@ 2d6ba7a221915bdf0311acc5641c7f3875cb793e jdk7-b100 2548ac036b8fca3326d058d758e6df8355a42469 jdk7-b101 88db80c8e49cea352c2900f689600dc410761c1f jdk7-b102 +64770970865839b0443066370e7d476ef47e90cd jdk7-b103 +10bc903a228d3a8efdf46fb8c3fcf82a59b88bc5 jdk7-b104 +1ce7938efb03224ccc8b3cdd7803eb39e889539c jdk7-b105 +6bdae472f77205046703b685eff2ac4f7a0ecf4e jdk7-b106
--- a/.hgtags-top-repo Thu Aug 12 23:21:17 2010 -0700 +++ b/.hgtags-top-repo Fri Aug 20 14:48:10 2010 -0400 @@ -77,3 +77,7 @@ b218a53ec7d3d42be61d31d6917a6c5c037b6f56 jdk7-b100 4193eaf5f1b82794c6a0fb1a8d11af43d1b1d611 jdk7-b101 a136a51f5113da4dad3853b74a8536ab583ab112 jdk7-b102 +be2aedc4e3b1751c1310f334242ba69e90867f38 jdk7-b103 +f8be576feefce0c6695f188ef97ec16b73ad9cfd jdk7-b104 +9f96a4269d7727dad68864eaab795eafce270311 jdk7-b105 +43096cccf1cee749c2f4e7714ee71f4e9e0f4d7f jdk7-b106
--- a/corba/.hgtags Thu Aug 12 23:21:17 2010 -0700 +++ b/corba/.hgtags Fri Aug 20 14:48:10 2010 -0400 @@ -77,3 +77,7 @@ a56d734a1e970e1a21a8f4feb13053e9a33674c7 jdk7-b100 86a239832646a74811695428984b6947c0bd6dc8 jdk7-b101 78561a95779090b5106c8d0f1a75360a027ef087 jdk7-b102 +11e7678c3eb169b77d9a9892fe5e3dfa1d1a0d51 jdk7-b103 +9607213481d400ac477183191cc080e1bef6f475 jdk7-b104 +6f21b030092fb61244cc8a0aedf8058f7c022b81 jdk7-b105 +519daea48888196af76a975a3b31258efa860bad jdk7-b106
--- a/hotspot/.hgtags Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/.hgtags Fri Aug 20 14:48:10 2010 -0400 @@ -107,3 +107,10 @@ 6c3a919105b68c15b7db923ec9a00006e9560910 jdk7-b101 ad1977f08c4d69162a0775fe3f9576b9fd521d10 hs19-b03 c5cadf1a07717955cf60dbaec16e35b529fd2cb0 jdk7-b102 +cb4250ef73b21de6c487ea14e2b0b99eed67b4b6 jdk7-b103 +e55900b5c1b865cac17e18abc639c7dc50de7fd8 hs19-b04 +b4acf10eb134fe930802c97e36db65e7ccb544b5 jdk7-b104 +6709c14587c2cc6faca208767335afeb01e33de5 jdk7-b105 +1b81ca701fa5fc30adc4cfdaa4bdd153df5e6c86 jdk7-b106 +cc3fdfeb54b049f18edcf3463e6ab051d0b7b609 hs19-b05 +688a538aa65412178286ae2a6b0c00b6711e121b hs19-b06
--- a/hotspot/agent/src/os/linux/ps_proc.c Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/agent/src/os/linux/ps_proc.c Fri Aug 20 14:48:10 2010 -0400 @@ -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/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Fri Aug 20 14:48:10 2010 -0400 @@ -297,6 +297,7 @@ case JVM_CONSTANT_NameAndType: return "JVM_CONSTANT_NameAndType"; case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle"; case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType"; + case JVM_CONSTANT_InvokeDynamic: return "JVM_CONSTANT_InvokeDynamic"; case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid"; case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass"; case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError"; @@ -355,6 +356,7 @@ case JVM_CONSTANT_NameAndType: case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodType: + case JVM_CONSTANT_InvokeDynamic: visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); break; } @@ -517,6 +519,18 @@ + ", type = " + signatureIndex); break; } + + case JVM_CONSTANT_InvokeDynamic: { + dos.writeByte(cpConstType); + int value = getIntAt(ci); + short bootstrapMethodIndex = (short) extractLowShortFromInt(value); + short nameAndTypeIndex = (short) extractHighShortFromInt(value); + dos.writeShort(bootstrapMethodIndex); + dos.writeShort(nameAndTypeIndex); + if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bootstrapMethodIndex + + ", N&T = " + nameAndTypeIndex); + break; + } default: throw new InternalError("unknown tag: " + cpConstType); } // switch
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Fri Aug 20 14:48:10 2010 -0400 @@ -42,6 +42,7 @@ public static final int JVM_CONSTANT_NameAndType = 12; public static final int JVM_CONSTANT_MethodHandle = 15; public static final int JVM_CONSTANT_MethodType = 16; + public static final int JVM_CONSTANT_InvokeDynamic = 17; // JVM_CONSTANT_MethodHandle subtypes public static final int JVM_REF_getField = 1;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Fri Aug 20 14:48:10 2010 -0400 @@ -303,12 +303,12 @@ case JVM_CONSTANT_MethodHandle: { dos.writeByte(cpConstType); int value = cpool.getIntAt(ci); - short refIndex = (short) extractHighShortFromInt(value); - byte refKind = (byte) extractLowShortFromInt(value); - dos.writeByte(refKind); - dos.writeShort(refIndex); - if (DEBUG) debugMessage("CP[" + ci + "] = MH index = " + refIndex - + ", kind = " + refKind); + short bootstrapMethodIndex = (short) extractLowShortFromInt(value); + short nameAndTypeIndex = (short) extractHighShortFromInt(value); + dos.writeShort(bootstrapMethodIndex); + dos.writeShort(nameAndTypeIndex); + if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + + bootstrapMethodIndex + ", N&T = " + nameAndTypeIndex); break; } @@ -321,6 +321,15 @@ break; } + case JVM_CONSTANT_InvokeDynamic: { + dos.writeByte(cpConstType); + int value = cpool.getIntAt(ci); + short refIndex = (short) value; + dos.writeShort(refIndex); + if (DEBUG) debugMessage("CP[" + ci + "] = MT index = " + refIndex); + break; + } + default: throw new InternalError("Unknown tag: " + cpConstType); } // switch
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Fri Aug 20 14:48:10 2010 -0400 @@ -582,6 +582,11 @@ buf.cell(Integer.toString(cpool.getIntAt(index))); break; + case JVM_CONSTANT_InvokeDynamic: + buf.cell("JVM_CONSTANT_InvokeDynamic"); + buf.cell(genLowHighShort(cpool.getIntAt(index))); + break; + default: throw new InternalError("unknown tag: " + ctag); }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Fri Aug 20 14:48:10 2010 -0400 @@ -40,6 +40,7 @@ private static int JVM_CONSTANT_NameAndType = 12; private static int JVM_CONSTANT_MethodHandle = 15; // JSR 292 private static int JVM_CONSTANT_MethodType = 16; // JSR 292 + private static int JVM_CONSTANT_InvokeDynamic = 17; // JSR 292 private static int JVM_CONSTANT_Invalid = 0; // For bad value initialization private static int JVM_CONSTANT_UnresolvedClass = 100; // Temporary tag until actual use private static int JVM_CONSTANT_ClassIndex = 101; // Temporary tag while constructing constant pool @@ -78,6 +79,7 @@ public boolean isUtf8() { return tag == JVM_CONSTANT_Utf8; } public boolean isMethodHandle() { return tag == JVM_CONSTANT_MethodHandle; } public boolean isMethodType() { return tag == JVM_CONSTANT_MethodType; } + public boolean isInvokeDynamic() { return tag == JVM_CONSTANT_InvokeDynamic; } public boolean isInvalid() { return tag == JVM_CONSTANT_Invalid; }
--- a/hotspot/make/Makefile Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/Makefile Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/defs.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/hotspot_version Fri Aug 20 14:48:10 2010 -0400 @@ -35,7 +35,7 @@ HS_MAJOR_VER=19 HS_MINOR_VER=0 -HS_BUILD_NUMBER=04 +HS_BUILD_NUMBER=06 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/hotspot/make/linux/Makefile Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/Makefile Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/build_vm_def.sh Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/buildtree.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/defs.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/gcc.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/product.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/sa.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/saproc.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/top.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/linux/makefiles/vm.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/solaris/makefiles/defs.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/make/solaris/makefiles/sparcWorks.make Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/bytecodeInterpreter_sparc.inline.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/javaFrameAnchor_sparc.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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/stubGenerator_sparc.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -1007,9 +1007,9 @@ __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, (*NOLp)); __ delayed()->cmp(to_from, byte_count); if (NOLp == NULL) - __ brx(Assembler::greaterEqual, false, Assembler::pt, no_overlap_target); + __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, no_overlap_target); else - __ brx(Assembler::greaterEqual, false, Assembler::pt, (*NOLp)); + __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, (*NOLp)); __ delayed()->nop(); }
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/javaFrameAnchor_x86.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os/linux/launcher/java_md.c Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os/linux/vm/globals_linux.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -82,3 +82,6 @@ return true; } + +void JavaThread::cache_global_variables() { } +
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -84,3 +84,6 @@ // nothing else to try return false; } + +void JavaThread::cache_global_variables() { } +
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/asm/codeBuffer.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_FrameMap.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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/ciEnv.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -728,8 +728,8 @@ } // Get the invoker methodOop from the constant pool. - intptr_t f2_value = cpool->cache()->main_entry_at(index)->f2(); - methodOop signature_invoker = methodOop(f2_value); + oop f1_value = cpool->cache()->main_entry_at(index)->f1(); + methodOop signature_invoker = methodOop(f1_value); assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), "correct result from LinkResolver::resolve_invokedynamic");
--- a/hotspot/src/share/vm/ci/ciField.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciField.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 } // ------------------------------------------------------------------ @@ -694,30 +708,21 @@ // ------------------------------------------------------------------ // ciMethod::is_method_handle_invoke // -// Return true if the method is a MethodHandle target. +// Return true if the method is an instance of one of the two +// signature-polymorphic MethodHandle methods, invokeExact or invokeGeneric. bool ciMethod::is_method_handle_invoke() const { - bool flag = (holder()->name() == ciSymbol::java_dyn_MethodHandle() && - methodOopDesc::is_method_handle_invoke_name(name()->sid())); -#ifdef ASSERT - if (is_loaded()) { - bool flag2 = ((flags().as_int() & JVM_MH_INVOKE_BITS) == JVM_MH_INVOKE_BITS); - { - VM_ENTRY_MARK; - bool flag3 = get_methodOop()->is_method_handle_invoke(); - assert(flag2 == flag3, "consistent"); - assert(flag == flag3, "consistent"); - } - } -#endif //ASSERT - return flag; + if (!is_loaded()) return false; + VM_ENTRY_MARK; + return get_methodOop()->is_method_handle_invoke(); } // ------------------------------------------------------------------ // ciMethod::is_method_handle_adapter // // Return true if the method is a generated MethodHandle adapter. +// These are built by MethodHandleCompiler. bool ciMethod::is_method_handle_adapter() const { - check_is_loaded(); + if (!is_loaded()) return false; VM_ENTRY_MARK; return get_methodOop()->is_method_handle_adapter(); }
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciMethod.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 @@ -122,7 +123,7 @@ if (!EnableMethodHandles || _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { classfile_parse_error( - (!EnableInvokeDynamic ? + (!EnableMethodHandles ? "This JVM does not support constant tag %u in class file %s" : "Class file version does not support constant tag %u in class file %s"), tag, CHECK); @@ -140,6 +141,22 @@ ShouldNotReachHere(); } break; + case JVM_CONSTANT_InvokeDynamic : + { + if (!EnableInvokeDynamic || + _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { + classfile_parse_error( + (!EnableInvokeDynamic ? + "This JVM does not support constant tag %u in class file %s" : + "Class file version does not support constant tag %u in class file %s"), + tag, CHECK); + } + cfs->guarantee_more(5, CHECK); // bsm_index, name_and_type_index, tag/access_flags + u2 bootstrap_method_index = cfs->get_u2_fast(); + u2 name_and_type_index = cfs->get_u2_fast(); + cp->invoke_dynamic_at_put(index, bootstrap_method_index, name_and_type_index); + } + break; case JVM_CONSTANT_Integer : { cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags @@ -414,6 +431,24 @@ ref_index, CHECK_(nullHandle)); } break; + case JVM_CONSTANT_InvokeDynamic : + { + int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index); + int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index); + check_property((bootstrap_method_ref_index == 0 && AllowTransitionalJSR292) + || + (valid_cp_range(bootstrap_method_ref_index, length) && + cp->tag_at(bootstrap_method_ref_index).is_method_handle()), + "Invalid constant pool index %u in class file %s", + bootstrap_method_ref_index, + CHECK_(nullHandle)); + check_property(valid_cp_range(name_and_type_ref_index, length) && + cp->tag_at(name_and_type_ref_index).is_name_and_type(), + "Invalid constant pool index %u in class file %s", + name_and_type_ref_index, + CHECK_(nullHandle)); + break; + } default: fatal(err_msg("bad constant pool tag value %u", cp->tag_at(index).value()));
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -2507,6 +2507,10 @@ int caller_bci, TRAPS) { Handle empty; + guarantee(bootstrap_method.not_null() && + java_dyn_MethodHandle::is_instance(bootstrap_method()), + "caller must supply a valid BSM"); + Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty)); MethodHandles::init_MemberName(caller_mname(), caller_method()); @@ -2537,20 +2541,61 @@ return call_site_oop; } -Handle SystemDictionary::find_bootstrap_method(KlassHandle caller, TRAPS) { +Handle SystemDictionary::find_bootstrap_method(methodHandle caller_method, int caller_bci, + int cache_index, TRAPS) { Handle empty; - if (!caller->oop_is_instance()) return empty; - - instanceKlassHandle ik(THREAD, caller()); - - oop boot_method_oop = ik->bootstrap_method(); - if (boot_method_oop != NULL) { + + constantPoolHandle pool; + { + klassOop caller = caller_method->method_holder(); + if (!Klass::cast(caller)->oop_is_instance()) return empty; + pool = constantPoolHandle(THREAD, instanceKlass::cast(caller)->constants()); + } + + int constant_pool_index = pool->cache()->entry_at(cache_index)->constant_pool_index(); + constantTag tag = pool->tag_at(constant_pool_index); + + if (tag.is_invoke_dynamic()) { + // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type] + // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry. + int bsm_index = pool->invoke_dynamic_bootstrap_method_ref_index_at(constant_pool_index); + if (bsm_index != 0) { + int bsm_index_in_cache = pool->cache()->entry_at(cache_index)->bootstrap_method_index_in_cache(); + DEBUG_ONLY(int bsm_index_2 = pool->cache()->entry_at(bsm_index_in_cache)->constant_pool_index()); + assert(bsm_index == bsm_index_2, "BSM constant lifted to cache"); + if (TraceMethodHandles) { + tty->print_cr("resolving bootstrap method for "PTR_FORMAT" at %d at cache[%d]CP[%d]...", + (intptr_t) caller_method(), caller_bci, cache_index, constant_pool_index); + } + oop bsm_oop = pool->resolve_cached_constant_at(bsm_index_in_cache, CHECK_(empty)); + if (TraceMethodHandles) { + tty->print_cr("bootstrap method for "PTR_FORMAT" at %d retrieved as "PTR_FORMAT":", + (intptr_t) caller_method(), caller_bci, (intptr_t) bsm_oop); + } + assert(bsm_oop->is_oop() + && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane"); + return Handle(THREAD, bsm_oop); + } + // else null BSM; fall through + } else if (tag.is_name_and_type()) { + // JSR 292 EDR does not have JVM_CONSTANT_InvokeDynamic + // a bare name&type defaults its BSM to null, so fall through... + } else { + ShouldNotReachHere(); // verifier does not allow this + } + + // Fall through to pick up the per-class bootstrap method. + // This mechanism may go away in the PFD. + assert(AllowTransitionalJSR292, "else the verifier should have stopped us already"); + oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method(); + if (bsm_oop != NULL) { if (TraceMethodHandles) { - tty->print_cr("bootstrap method for "PTR_FORMAT" cached as "PTR_FORMAT":", ik(), boot_method_oop); + tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":", + (intptr_t) caller_method(), (intptr_t) bsm_oop); } - assert(boot_method_oop->is_oop() - && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane"); - return Handle(THREAD, boot_method_oop); + assert(bsm_oop->is_oop() + && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane"); + return Handle(THREAD, bsm_oop); } return empty;
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -492,7 +492,10 @@ TRAPS); // coordinate with Java about bootstrap methods - static Handle find_bootstrap_method(KlassHandle caller, TRAPS); + static Handle find_bootstrap_method(methodHandle caller_method, + int caller_bci, // N.B. must be an invokedynamic + int cache_index, // must be corresponding main_entry + TRAPS); // Utility for printing loader "name" as part of tracing constraints static const char* loader_name(oop loader) {
--- a/hotspot/src/share/vm/classfile/verificationType.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/classfile/verificationType.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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; } @@ -1913,7 +1909,8 @@ unsigned int types = (opcode == Bytecodes::_invokeinterface ? 1 << JVM_CONSTANT_InterfaceMethodref : opcode == Bytecodes::_invokedynamic - ? 1 << JVM_CONSTANT_NameAndType + ? (1 << JVM_CONSTANT_NameAndType + |1 << JVM_CONSTANT_InvokeDynamic) : 1 << JVM_CONSTANT_Methodref); verify_cp_type(index, cp, types, CHECK_VERIFY(this));
--- a/hotspot/src/share/vm/code/codeBlob.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/code/codeBlob.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -202,6 +202,11 @@ //---------------------------------------------------------------------------------------------------- // Implementation of AdapterBlob +AdapterBlob::AdapterBlob(int size, CodeBuffer* cb) : + BufferBlob("I2C/C2I adapters", size, cb) { + CodeCache::commit(this); +} + AdapterBlob* AdapterBlob::create(CodeBuffer* cb) { ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock @@ -210,7 +215,6 @@ { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); blob = new (size) AdapterBlob(size, cb); - CodeCache::commit(blob); } // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); @@ -560,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()); } @@ -633,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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/code/codeBlob.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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; }; @@ -219,8 +220,7 @@ class AdapterBlob: public BufferBlob { private: - AdapterBlob(int size) : BufferBlob("I2C/C2I adapters", size) {} - AdapterBlob(int size, CodeBuffer* cb) : BufferBlob("I2C/C2I adapters", size, cb) {} + AdapterBlob(int size, CodeBuffer* cb); public: // Creation @@ -293,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; }; @@ -318,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; }; @@ -374,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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/code/nmethod.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/code/vtableStubs.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/code/vtableStubs.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/compiler/disassembler.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -664,19 +664,14 @@ return; } - // XXX use a global constant instead of 64! - typedef struct OopTaskQueuePadded { - OopTaskQueue work_queue; - char pad[64 - sizeof(OopTaskQueue)]; // prevent false sharing - } OopTaskQueuePadded; - + typedef Padded<OopTaskQueue> PaddedOopTaskQueue; for (i = 0; i < num_queues; i++) { - OopTaskQueuePadded *q_padded = new OopTaskQueuePadded(); - if (q_padded == NULL) { + PaddedOopTaskQueue *q = new PaddedOopTaskQueue(); + if (q == NULL) { warning("work_queue allocation failure."); return; } - _task_queues->register_queue(i, &q_padded->work_queue); + _task_queues->register_queue(i, q); } for (i = 0; i < num_queues; i++) { _task_queues->queue(i)->initialize();
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -234,6 +234,11 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); if (_gc_cause != GCCause::_gc_locker && gch->total_full_collections_completed() <= _full_gc_count_before) { + // maybe we should change the condition to test _gc_cause == + // GCCause::_java_lang_system_gc, instead of + // _gc_cause != GCCause::_gc_locker + assert(_gc_cause == GCCause::_java_lang_system_gc, + "the only way to get here if this was a System.gc()-induced GC"); assert(ExplicitGCInvokesConcurrent, "Error"); // Now, wait for witnessing concurrent gc cycle to complete, // but do so in native mode, because we want to lock the
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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/concurrentG1Refine.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -271,21 +271,16 @@ if (cas_res == prev_epoch_entry) { // We successfully updated the card num value in the epoch entry count_ptr->_count = 0; // initialize counter for new card num + jbyte* old_card_ptr = card_num_2_ptr(old_card_num); // Even though the region containg the card at old_card_num was not // in the young list when old_card_num was recorded in the epoch // cache it could have been added to the free list and subsequently - // added to the young list in the intervening time. If the evicted - // card is in a young region just return the card_ptr and the evicted - // card will not be cleaned. See CR 6817995. - - jbyte* old_card_ptr = card_num_2_ptr(old_card_num); - if (is_young_card(old_card_ptr)) { - *count = 0; - // We can defer the processing of card_ptr - *defer = true; - return card_ptr; - } + // added to the young list in the intervening time. See CR 6817995. + // We do not deal with this case here - it will be handled in + // HeapRegion::oops_on_card_seq_iterate_careful after it has been + // determined that the region containing the card has been allocated + // to, and it's safe to check the young type of the region. // We do not want to defer processing of card_ptr in this case // (we need to refine old_card_ptr and card_ptr) @@ -301,22 +296,22 @@ jbyte* cached_ptr = add_card_count(card_ptr, &count, defer); assert(cached_ptr != NULL, "bad cached card ptr"); - if (is_young_card(cached_ptr)) { - // The region containing cached_ptr has been freed during a clean up - // pause, reallocated, and tagged as young. - assert(cached_ptr != card_ptr, "shouldn't be"); + // We've just inserted a card pointer into the card count cache + // and got back the card that we just inserted or (evicted) the + // previous contents of that count slot. - // We've just inserted a new old-gen card pointer into the card count - // cache and evicted the previous contents of that count slot. - // The evicted card pointer has been determined to be in a young region - // and so cannot be the newly inserted card pointer (that will be - // in an old region). - // The count for newly inserted card will be set to zero during the - // insertion, so we don't want to defer the cleaning of the newly - // inserted card pointer. - assert(*defer == false, "deferring non-hot card"); - return NULL; - } + // The card we got back could be in a young region. When the + // returned card (if evicted) was originally inserted, we had + // determined that its containing region was not young. However + // it is possible for the region to be freed during a cleanup + // pause, then reallocated and tagged as young which will result + // in the returned card residing in a young region. + // + // We do not deal with this case here - the change from non-young + // to young could be observed at any time - it will be handled in + // HeapRegion::oops_on_card_seq_iterate_careful after it has been + // determined that the region containing the card has been allocated + // to. // The card pointer we obtained from card count cache is not hot // so do not store it in the cache; return it for immediate @@ -325,7 +320,7 @@ return cached_ptr; } - // Otherwise, the pointer we got from the _card_counts is hot. + // Otherwise, the pointer we got from the _card_counts cache is hot. jbyte* res = NULL; MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag); if (_n_hot == _hot_cache_size) { @@ -338,17 +333,8 @@ if (_hot_cache_idx == _hot_cache_size) _hot_cache_idx = 0; _n_hot++; - if (res != NULL) { - // Even though the region containg res was not in the young list - // when it was recorded in the hot cache it could have been added - // to the free list and subsequently added to the young list in - // the intervening time. If res is in a young region, return NULL - // so that res is not cleaned. See CR 6817995. - - if (is_young_card(res)) { - res = NULL; - } - } + // The card obtained from the hot card cache could be in a young + // region. See above on how this can happen. return res; }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -266,6 +266,12 @@ _cm->clearNextBitmap(); _sts.leave(); } + + // Update the number of full collections that have been + // completed. This will also notify the FullGCCount_lock in case a + // Java thread is waiting for a full GC to happen (e.g., it + // called System.gc() with +ExplicitGCInvokesConcurrent). + g1->increment_full_collections_completed(true /* outer */); } assert(_should_terminate, "just checking");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -638,6 +638,11 @@ // Now retry the allocation. if (_cur_alloc_region != NULL) { + if (allocated_young_region != NULL) { + // We need to ensure that the store to top does not + // float above the setting of the young type. + OrderAccess::storestore(); + } res = _cur_alloc_region->allocate(word_size); } } @@ -809,7 +814,8 @@ } }; -void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs, +void G1CollectedHeap::do_collection(bool explicit_gc, + bool clear_all_soft_refs, size_t word_size) { if (GC_locker::check_active_before_gc()) { return; // GC is disabled (e.g. JNI GetXXXCritical operation) @@ -821,10 +827,6 @@ Universe::print_heap_before_gc(); } - if (full && DisableExplicitGC) { - return; - } - assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread"); @@ -837,9 +839,11 @@ IsGCActiveMark x; // Timing + bool system_gc = (gc_cause() == GCCause::_java_lang_system_gc); + assert(!system_gc || explicit_gc, "invariant"); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); - TraceTime t(full ? "Full GC (System.gc())" : "Full GC", + TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty); TraceMemoryManagerStats tms(true /* fullGC */); @@ -944,7 +948,7 @@ heap_region_iterate(&rs_clear); // Resize the heap if necessary. - resize_if_necessary_after_full_collection(full ? 0 : word_size); + resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); if (_cg1r->use_cache()) { _cg1r->clear_and_record_card_counts(); @@ -1009,13 +1013,18 @@ "young list should be empty at this point"); } + // Update the number of full collections that have been completed. + increment_full_collections_completed(false /* outer */); + if (PrintHeapAtGC) { Universe::print_heap_after_gc(); } } void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { - do_collection(true, clear_all_soft_refs, 0); + do_collection(true, /* explicit_gc */ + clear_all_soft_refs, + 0 /* word_size */); } // This code is mostly copied from TenuredGeneration. @@ -1331,6 +1340,7 @@ _young_list(new YoungList(this)), _gc_time_stamp(0), _surviving_young_words(NULL), + _full_collections_completed(0), _in_cset_fast_test(NULL), _in_cset_fast_test_base(NULL), _dirty_cards_region_list(NULL) { @@ -1689,6 +1699,51 @@ return car->free(); } +bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { + return + ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || + (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); +} + +void G1CollectedHeap::increment_full_collections_completed(bool outer) { + MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); + + // We have already incremented _total_full_collections at the start + // of the GC, so total_full_collections() represents how many full + // collections have been started. + unsigned int full_collections_started = total_full_collections(); + + // Given that this method is called at the end of a Full GC or of a + // concurrent cycle, and those can be nested (i.e., a Full GC can + // interrupt a concurrent cycle), the number of full collections + // completed should be either one (in the case where there was no + // nesting) or two (when a Full GC interrupted a concurrent cycle) + // behind the number of full collections started. + + // This is the case for the inner caller, i.e. a Full GC. + assert(outer || + (full_collections_started == _full_collections_completed + 1) || + (full_collections_started == _full_collections_completed + 2), + err_msg("for inner caller: full_collections_started = %u " + "is inconsistent with _full_collections_completed = %u", + full_collections_started, _full_collections_completed)); + + // This is the case for the outer caller, i.e. the concurrent cycle. + assert(!outer || + (full_collections_started == _full_collections_completed + 1), + err_msg("for outer caller: full_collections_started = %u " + "is inconsistent with _full_collections_completed = %u", + full_collections_started, _full_collections_completed)); + + _full_collections_completed += 1; + + // This notify_all() will ensure that a thread that called + // System.gc() with (with ExplicitGCInvokesConcurrent set or not) + // and it's waiting for a full GC to finish will be woken up. It is + // waiting in VM_G1IncCollectionPause::doit_epilogue(). + FullGCCount_lock->notify_all(); +} + void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { assert(Thread::current()->is_VM_thread(), "Precondition#1"); assert(Heap_lock->is_locked(), "Precondition#2"); @@ -1709,25 +1764,41 @@ // The caller doesn't have the Heap_lock assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); - int gc_count_before; + unsigned int gc_count_before; + unsigned int full_gc_count_before; { MutexLocker ml(Heap_lock); // Read the GC count while holding the Heap_lock gc_count_before = SharedHeap::heap()->total_collections(); + full_gc_count_before = SharedHeap::heap()->total_full_collections(); // Don't want to do a GC until cleanup is completed. wait_for_cleanup_complete(); - } // We give up heap lock; VMThread::execute gets it back below - switch (cause) { - case GCCause::_scavenge_alot: { - // Do an incremental pause, which might sometimes be abandoned. - VM_G1IncCollectionPause op(gc_count_before, cause); + + // We give up heap lock; VMThread::execute gets it back below + } + + if (should_do_concurrent_full_gc(cause)) { + // Schedule an initial-mark evacuation pause that will start a + // concurrent cycle. + VM_G1IncCollectionPause op(gc_count_before, + true, /* should_initiate_conc_mark */ + g1_policy()->max_pause_time_ms(), + cause); + VMThread::execute(&op); + } else { + if (cause == GCCause::_gc_locker + DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { + + // Schedule a standard evacuation pause. + VM_G1IncCollectionPause op(gc_count_before, + false, /* should_initiate_conc_mark */ + g1_policy()->max_pause_time_ms(), + cause); VMThread::execute(&op); - break; - } - default: { - // In all other cases, we currently do a full gc. - VM_G1CollectFull op(gc_count_before, cause); + } else { + // Schedule a Full GC. + VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause); VMThread::execute(&op); } } @@ -1989,6 +2060,11 @@ void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, HeapRegionClosure *cl) { + if (r == NULL) { + // The CSet is empty so there's nothing to do. + return; + } + assert(r->in_collection_set(), "Start region must be a member of the collection set."); HeapRegion* cur = r; @@ -2481,11 +2557,13 @@ } void G1CollectedHeap::do_collection_pause() { + assert(Heap_lock->owned_by_self(), "we assume we'reholding the Heap_lock"); + // Read the GC count while holding the Heap_lock // we need to do this _before_ wait_for_cleanup_complete(), to // ensure that we do not give up the heap lock and potentially // pick up the wrong count - int gc_count_before = SharedHeap::heap()->total_collections(); + unsigned int gc_count_before = SharedHeap::heap()->total_collections(); // Don't want to do a GC pause while cleanup is being completed! wait_for_cleanup_complete(); @@ -2493,7 +2571,10 @@ g1_policy()->record_stop_world_start(); { MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back - VM_G1IncCollectionPause op(gc_count_before); + VM_G1IncCollectionPause op(gc_count_before, + false, /* should_initiate_conc_mark */ + g1_policy()->max_pause_time_ms(), + GCCause::_g1_inc_collection_pause); VMThread::execute(&op); } } @@ -2612,7 +2693,7 @@ }; void -G1CollectedHeap::do_collection_pause_at_safepoint() { +G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { if (GC_locker::check_active_before_gc()) { return; // GC is disabled (e.g. JNI GetXXXCritical operation) } @@ -2637,8 +2718,12 @@ else strcat(verbose_str, "(partial)"); } - if (g1_policy()->during_initial_mark_pause()) + if (g1_policy()->during_initial_mark_pause()) { strcat(verbose_str, " (initial-mark)"); + // We are about to start a marking cycle, so we increment the + // full collection counter. + increment_total_full_collections(); + } // if PrintGCDetails is on, we'll print long statistics information // in the collector policy code, so let's not print this as the output @@ -2661,7 +2746,6 @@ "young list should be well formed"); } - bool abandoned = false; { // Call to jvmpi::post_class_unload_events must occur outside of active GC IsGCActiveMark x; @@ -2743,7 +2827,7 @@ // Now choose the CS. We may abandon a pause if we find no // region that will fit in the MMU pause. - bool abandoned = g1_policy()->choose_collection_set(); + bool abandoned = g1_policy()->choose_collection_set(target_pause_time_ms); // Nothing to do if we were unable to choose a collection set. if (!abandoned) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -277,6 +277,18 @@ void update_surviving_young_words(size_t* surv_young_words); void cleanup_surviving_young_words(); + // It decides whether an explicit GC should start a concurrent cycle + // instead of doing a STW GC. Currently, a concurrent cycle is + // explicitly started if: + // (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or + // (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent. + bool should_do_concurrent_full_gc(GCCause::Cause cause); + + // Keeps track of how many "full collections" (i.e., Full GCs or + // concurrent cycles) we have completed. The number of them we have + // started is maintained in _total_full_collections in CollectedHeap. + volatile unsigned int _full_collections_completed; + protected: // Returns "true" iff none of the gc alloc regions have any allocations @@ -356,13 +368,14 @@ // GC pause. void retire_alloc_region(HeapRegion* alloc_region, bool par); - // Helper function for two callbacks below. - // "full", if true, indicates that the GC is for a System.gc() request, - // and should collect the entire heap. If "clear_all_soft_refs" is true, - // all soft references are cleared during the GC. If "full" is false, - // "word_size" describes the allocation that the GC should - // attempt (at least) to satisfy. - void do_collection(bool full, bool clear_all_soft_refs, + // - if explicit_gc is true, the GC is for a System.gc() or a heap + // inspection request and should collect the entire heap + // - if clear_all_soft_refs is true, all soft references are cleared + // during the GC + // - if explicit_gc is false, word_size describes the allocation that + // the GC should attempt (at least) to satisfy + void do_collection(bool explicit_gc, + bool clear_all_soft_refs, size_t word_size); // Callback from VM_G1CollectFull operation. @@ -431,6 +444,26 @@ _in_cset_fast_test_length * sizeof(bool)); } + // This is called at the end of either a concurrent cycle or a Full + // GC to update the number of full collections completed. Those two + // can happen in a nested fashion, i.e., we start a concurrent + // cycle, a Full GC happens half-way through it which ends first, + // and then the cycle notices that a Full GC happened and ends + // too. The outer parameter is a boolean to help us do a bit tighter + // consistency checking in the method. If outer is false, the caller + // is the inner caller in the nesting (i.e., the Full GC). If outer + // is true, the caller is the outer caller in this nesting (i.e., + // the concurrent cycle). Further nesting is not currently + // supported. The end of the this call also notifies the + // FullGCCount_lock in case a Java thread is waiting for a full GC + // to happen (e.g., it called System.gc() with + // +ExplicitGCInvokesConcurrent). + void increment_full_collections_completed(bool outer); + + unsigned int full_collections_completed() { + return _full_collections_completed; + } + protected: // Shrink the garbage-first heap by at most the given size (in bytes!). @@ -444,7 +477,7 @@ // The guts of the incremental collection pause, executed by the vm // thread. - virtual void do_collection_pause_at_safepoint(); + virtual void do_collection_pause_at_safepoint(double target_pause_time_ms); // Actually do the work of evacuating the collection set. virtual void evacuate_collection_set();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -154,7 +154,6 @@ _known_garbage_bytes(0), _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)), - _target_pause_time_ms(-1.0), _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)), @@ -1635,8 +1634,6 @@ double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); // </NEW PREDICTION> - - _target_pause_time_ms = -1.0; } // <NEW PREDICTION> @@ -2366,7 +2363,6 @@ if (reached_target_length) { assert( young_list_length > 0 && _g1->young_list()->length() > 0, "invariant" ); - _target_pause_time_ms = max_pause_time_ms; return true; } } else { @@ -2398,6 +2394,17 @@ } #endif +bool +G1CollectorPolicy::force_initial_mark_if_outside_cycle() { + bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle(); + if (!during_cycle) { + set_initiate_conc_mark_if_possible(); + return true; + } else { + return false; + } +} + void G1CollectorPolicy::decide_on_conc_mark_initiation() { // We are about to decide on whether this pause will be an @@ -2864,7 +2871,8 @@ #endif // !PRODUCT bool -G1CollectorPolicy_BestRegionsFirst::choose_collection_set() { +G1CollectorPolicy_BestRegionsFirst::choose_collection_set( + double target_pause_time_ms) { // Set this here - in case we're not doing young collections. double non_young_start_time_sec = os::elapsedTime(); @@ -2877,26 +2885,19 @@ start_recording_regions(); - guarantee(_target_pause_time_ms > -1.0 - NOT_PRODUCT(|| Universe::heap()->gc_cause() == GCCause::_scavenge_alot), - "_target_pause_time_ms should have been set!"); -#ifndef PRODUCT - if (_target_pause_time_ms <= -1.0) { - assert(ScavengeALot && Universe::heap()->gc_cause() == GCCause::_scavenge_alot, "Error"); - _target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; - } -#endif - assert(_collection_set == NULL, "Precondition"); + guarantee(target_pause_time_ms > 0.0, + err_msg("target_pause_time_ms = %1.6lf should be positive", + target_pause_time_ms)); + guarantee(_collection_set == NULL, "Precondition"); double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); double predicted_pause_time_ms = base_time_ms; - double target_time_ms = _target_pause_time_ms; - double time_remaining_ms = target_time_ms - base_time_ms; + double time_remaining_ms = target_pause_time_ms - base_time_ms; // the 10% and 50% values are arbitrary... - if (time_remaining_ms < 0.10*target_time_ms) { - time_remaining_ms = 0.50 * target_time_ms; + if (time_remaining_ms < 0.10 * target_pause_time_ms) { + time_remaining_ms = 0.50 * target_pause_time_ms; _within_target = false; } else { _within_target = true; @@ -3059,7 +3060,18 @@ _recorded_non_young_cset_choice_time_ms = (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; - return abandon_collection; + // Here we are supposed to return whether the pause should be + // abandoned or not (i.e., whether the collection set is empty or + // not). However, this introduces a subtle issue when a pause is + // initiated explicitly with System.gc() and + // +ExplicitGCInvokesConcurrent (see Comment #2 in CR 6944166), it's + // supposed to start a marking cycle, and it's abandoned. So, by + // returning false here we are telling the caller never to consider + // a pause to be abandoned. We'll actually remove all the code + // associated with abandoned pauses as part of CR 6963209, but we are + // just disabling them this way for the moment to avoid increasing + // further the amount of changes for CR 6944166. + return false; } void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -199,8 +199,6 @@ size_t _young_cset_length; bool _last_young_gc_full; - double _target_pause_time_ms; - unsigned _full_young_pause_num; unsigned _partial_young_pause_num; @@ -526,6 +524,10 @@ return _mmu_tracker; } + double max_pause_time_ms() { + return _mmu_tracker->max_gc_time() * 1000.0; + } + double predict_init_time_ms() { return get_new_prediction(_concurrent_mark_init_times_ms); } @@ -1008,7 +1010,7 @@ // Choose a new collection set. Marks the chosen regions as being // "in_collection_set", and links them together. The head and number of // the collection set are available via access methods. - virtual bool choose_collection_set() = 0; + virtual bool choose_collection_set(double target_pause_time_ms) = 0; // The head of the list (via "next_in_collection_set()") representing the // current collection set. @@ -1077,6 +1079,12 @@ void set_during_initial_mark_pause() { _during_initial_mark_pause = true; } void clear_during_initial_mark_pause(){ _during_initial_mark_pause = false; } + // This sets the initiate_conc_mark_if_possible() flag to start a + // new cycle, as long as we are not already in one. It's best if it + // is called during a safepoint when the test whether a cycle is in + // progress or not is stable. + bool force_initial_mark_if_outside_cycle(); + // This is called at the very beginning of an evacuation pause (it // has to be the first thing that the pause does). If // initiate_conc_mark_if_possible() is true, and the concurrent @@ -1259,7 +1267,7 @@ // If the estimated is less then desirable, resize if possible. void expand_if_possible(size_t numRegions); - virtual bool choose_collection_set(); + virtual bool choose_collection_set(double target_pause_time_ms); virtual void record_collection_pause_start(double start_time_sec, size_t start_used); virtual void record_concurrent_mark_cleanup_end(size_t freed_bytes,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -676,9 +676,27 @@ // We must complete this write before we do any of the reads below. OrderAccess::storeload(); // And process it, being careful of unallocated portions of TLAB's. + + // The region for the current card may be a young region. The + // current card may have been a card that was evicted from the + // card cache. When the card was inserted into the cache, we had + // determined that its region was non-young. While in the cache, + // the region may have been freed during a cleanup pause, reallocated + // and tagged as young. + // + // We wish to filter out cards for such a region but the current + // thread, if we're running conucrrently, may "see" the young type + // change at any time (so an earlier "is_young" check may pass or + // fail arbitrarily). We tell the iteration code to perform this + // filtering when it has been determined that there has been an actual + // allocation in this region and making it safe to check the young type. + bool filter_young = true; + HeapWord* stop_point = r->oops_on_card_seq_iterate_careful(dirtyRegion, - &filter_then_update_rs_oop_cl); + &filter_then_update_rs_oop_cl, + filter_young); + // If stop_point is non-null, then we encountered an unallocated region // (perhaps the unfilled portion of a TLAB.) For now, we'll dirty the // card and re-enqueue: if we put off the card until a GC pause, then the @@ -789,8 +807,14 @@ if (r == NULL) { assert(_g1->is_in_permanent(start), "Or else where?"); } else { - guarantee(!r->is_young(), "It was evicted in the current minor cycle."); - // Process card pointer we get back from the hot card cache + // Checking whether the region we got back from the cache + // is young here is inappropriate. The region could have been + // freed, reallocated and tagged as young while in the cache. + // Hence we could see its young type change at any time. + // + // Process card pointer we get back from the hot card cache. This + // will check whether the region containing the card is young + // _after_ checking that the region has been allocated from. concurrentRefineOneCard_impl(res, worker_i); } }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -658,7 +658,8 @@ HeapWord* HeapRegion:: oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl) { + FilterOutOfRegionClosure* cl, + bool filter_young) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); // If we're within a stop-world GC, then we might look at a card in a @@ -672,6 +673,16 @@ if (mr.is_empty()) return NULL; // Otherwise, find the obj that extends onto mr.start(). + // The intersection of the incoming mr (for the card) and the + // allocated part of the region is non-empty. This implies that + // we have actually allocated into this region. The code in + // G1CollectedHeap.cpp that allocates a new region sets the + // is_young tag on the region before allocating. Thus we + // safely know if this region is young. + if (is_young() && filter_young) { + return NULL; + } + // We used to use "block_start_careful" here. But we're actually happy // to update the BOT while we do this... HeapWord* cur = block_start(mr.start());
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -252,7 +252,7 @@ // survivor }; - YoungType _young_type; + volatile YoungType _young_type; int _young_index_in_cset; SurvRateGroup* _surv_rate_group; int _age_index; @@ -726,9 +726,12 @@ HeapWord* object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl); + // In this version - if filter_young is true and the region + // is a young region then we skip the iteration. HeapWord* oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl); + FilterOutOfRegionClosure* cl, + bool filter_young); // The region "mr" is entirely in "this", and starts and ends at block // boundaries. The caller declares that all the contained blocks are
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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/gc_implementation/g1/vm_operations_g1.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -42,8 +42,65 @@ void VM_G1IncCollectionPause::doit() { JvmtiGCForAllocationMarker jgcm; G1CollectedHeap* g1h = G1CollectedHeap::heap(); + assert(!_should_initiate_conc_mark || + ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || + (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)), + "only a GC locker or a System.gc() induced GC should start a cycle"); + GCCauseSetter x(g1h, _gc_cause); - g1h->do_collection_pause_at_safepoint(); + if (_should_initiate_conc_mark) { + // It's safer to read full_collections_completed() here, given + // that noone else will be updating it concurrently. Since we'll + // only need it if we're initiating a marking cycle, no point in + // setting it earlier. + _full_collections_completed_before = g1h->full_collections_completed(); + + // At this point we are supposed to start a concurrent cycle. We + // will do so if one is not already in progress. + bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle(); + } + g1h->do_collection_pause_at_safepoint(_target_pause_time_ms); +} + +void VM_G1IncCollectionPause::doit_epilogue() { + VM_GC_Operation::doit_epilogue(); + + // If the pause was initiated by a System.gc() and + // +ExplicitGCInvokesConcurrent, we have to wait here for the cycle + // that just started (or maybe one that was already in progress) to + // finish. + if (_gc_cause == GCCause::_java_lang_system_gc && + _should_initiate_conc_mark) { + assert(ExplicitGCInvokesConcurrent, + "the only way to be here is if ExplicitGCInvokesConcurrent is set"); + + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + + // In the doit() method we saved g1h->full_collections_completed() + // in the _full_collections_completed_before field. We have to + // wait until we observe that g1h->full_collections_completed() + // has increased by at least one. This can happen if a) we started + // a cycle and it completes, b) a cycle already in progress + // completes, or c) a Full GC happens. + + // If the condition has already been reached, there's no point in + // actually taking the lock and doing the wait. + if (g1h->full_collections_completed() <= + _full_collections_completed_before) { + // The following is largely copied from CMS + + Thread* thr = Thread::current(); + assert(thr->is_Java_thread(), "invariant"); + JavaThread* jt = (JavaThread*)thr; + ThreadToNativeFromVM native(jt); + + MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); + while (g1h->full_collections_completed() <= + _full_collections_completed_before) { + FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag); + } + } + } } void VM_CGC_Operation::doit() {
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -31,13 +31,12 @@ // - VM_G1PopRegionCollectionPause class VM_G1CollectFull: public VM_GC_Operation { - private: public: - VM_G1CollectFull(int gc_count_before, - GCCause::Cause gc_cause) - : VM_GC_Operation(gc_count_before) - { - _gc_cause = gc_cause; + VM_G1CollectFull(unsigned int gc_count_before, + unsigned int full_gc_count_before, + GCCause::Cause cause) + : VM_GC_Operation(gc_count_before, full_gc_count_before) { + _gc_cause = cause; } ~VM_G1CollectFull() {} virtual VMOp_Type type() const { return VMOp_G1CollectFull; } @@ -67,12 +66,28 @@ }; class VM_G1IncCollectionPause: public VM_GC_Operation { - public: - VM_G1IncCollectionPause(int gc_count_before, - GCCause::Cause gc_cause = GCCause::_g1_inc_collection_pause) : - VM_GC_Operation(gc_count_before) { _gc_cause = gc_cause; } +private: + bool _should_initiate_conc_mark; + double _target_pause_time_ms; + unsigned int _full_collections_completed_before; +public: + VM_G1IncCollectionPause(unsigned int gc_count_before, + bool should_initiate_conc_mark, + double target_pause_time_ms, + GCCause::Cause cause) + : VM_GC_Operation(gc_count_before), + _full_collections_completed_before(0), + _should_initiate_conc_mark(should_initiate_conc_mark), + _target_pause_time_ms(target_pause_time_ms) { + guarantee(target_pause_time_ms > 0.0, + err_msg("target_pause_time_ms = %1.6lf should be positive", + target_pause_time_ms)); + + _gc_cause = cause; + } virtual VMOp_Type type() const { return VMOp_G1IncCollectionPause; } virtual void doit(); + virtual void doit_epilogue(); virtual const char* name() const { return "garbage-first incremental collection pause"; }
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1 Fri Aug 20 14:48:10 2010 -0400 @@ -367,4 +367,6 @@ vm_operations_g1.cpp vm_operations_g1.hpp vm_operations_g1.cpp g1CollectedHeap.inline.hpp +vm_operations_g1.cpp g1CollectorPolicy.hpp +vm_operations_g1.cpp interfaceSupport.hpp vm_operations_g1.cpp isGCActiveMark.hpp
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -539,10 +539,9 @@ guarantee(_task_queues != NULL, "task_queues allocation failure."); for (uint i1 = 0; i1 < ParallelGCThreads; i1++) { - ObjToScanQueuePadded *q_padded = new ObjToScanQueuePadded(); - guarantee(q_padded != NULL, "work_queue Allocation failure."); - - _task_queues->register_queue(i1, &q_padded->work_queue); + ObjToScanQueue *q = new ObjToScanQueue(); + guarantee(q != NULL, "work_queue Allocation failure."); + _task_queues->register_queue(i1, q); } for (uint i2 = 0; i2 < ParallelGCThreads; i2++)
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -33,8 +33,8 @@ // but they must be here to allow ParScanClosure::do_oop_work to be defined // in genOopClosures.inline.hpp. -typedef OopTaskQueue ObjToScanQueue; -typedef OopTaskQueueSet ObjToScanQueueSet; +typedef Padded<OopTaskQueue> ObjToScanQueue; +typedef GenericTaskQueueSet<ObjToScanQueue> ObjToScanQueueSet; // Enable this to get push/pop/steal stats. const int PAR_STATS_ENABLED = 0; @@ -304,12 +304,6 @@ friend class ParEvacuateFollowersClosure; private: - // XXX use a global constant instead of 64! - struct ObjToScanQueuePadded { - ObjToScanQueue work_queue; - char pad[64 - sizeof(ObjToScanQueue)]; // prevent false sharing - }; - // The per-worker-thread work queues ObjToScanQueueSet* _task_queues;
--- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -26,7 +26,8 @@ class ParScanThreadState; class ParNewGeneration; -typedef OopTaskQueueSet ObjToScanQueueSet; +typedef Padded<OopTaskQueue> ObjToScanQueue; +typedef GenericTaskQueueSet<ObjToScanQueue> ObjToScanQueueSet; class ParallelTaskTerminator; class ParScanClosure: public OopsInGenClosure {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -90,10 +90,7 @@ } void PSPromotionManager::post_scavenge() { -#if PS_PM_STATS - print_stats(); -#endif // PS_PM_STATS - + TASKQUEUE_STATS_ONLY(if (PrintGCDetails && ParallelGCVerbose) print_stats()); for (uint i = 0; i < ParallelGCThreads + 1; i++) { PSPromotionManager* manager = manager_array(i); if (UseDepthFirstScavengeOrder) { @@ -105,37 +102,58 @@ } } -#if PS_PM_STATS - +#if TASKQUEUE_STATS void -PSPromotionManager::print_stats(uint i) { - tty->print_cr("---- GC Worker %2d Stats", i); - tty->print_cr(" total pushes %8d", _total_pushes); - tty->print_cr(" masked pushes %8d", _masked_pushes); - tty->print_cr(" overflow pushes %8d", _overflow_pushes); - tty->print_cr(" max overflow length %8d", _max_overflow_length); - tty->print_cr(""); - tty->print_cr(" arrays chunked %8d", _arrays_chunked); - tty->print_cr(" array chunks processed %8d", _array_chunks_processed); - tty->print_cr(""); - tty->print_cr(" total steals %8d", _total_steals); - tty->print_cr(" masked steals %8d", _masked_steals); - tty->print_cr(""); +PSPromotionManager::print_taskqueue_stats(uint i) const { + const TaskQueueStats& stats = depth_first() ? + _claimed_stack_depth.stats : _claimed_stack_breadth.stats; + tty->print("%3u ", i); + stats.print(); + tty->cr(); } void +PSPromotionManager::print_local_stats(uint i) const { + #define FMT " " SIZE_FORMAT_W(10) + tty->print_cr("%3u" FMT FMT FMT FMT, i, _masked_pushes, _masked_steals, + _arrays_chunked, _array_chunks_processed); + #undef FMT +} + +static const char* const pm_stats_hdr[] = { + " --------masked------- arrays array", + "thr push steal chunked chunks", + "--- ---------- ---------- ---------- ----------" +}; + +void PSPromotionManager::print_stats() { - tty->print_cr("== GC Tasks Stats (%s), GC %3d", - (UseDepthFirstScavengeOrder) ? "Depth-First" : "Breadth-First", + const bool df = UseDepthFirstScavengeOrder; + tty->print_cr("== GC Task Stats (%s-First), GC %3d", df ? "Depth" : "Breadth", Universe::heap()->total_collections()); - for (uint i = 0; i < ParallelGCThreads+1; ++i) { - PSPromotionManager* manager = manager_array(i); - manager->print_stats(i); + tty->print("thr "); TaskQueueStats::print_header(1); tty->cr(); + tty->print("--- "); TaskQueueStats::print_header(2); tty->cr(); + for (uint i = 0; i < ParallelGCThreads + 1; ++i) { + manager_array(i)->print_taskqueue_stats(i); + } + + const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); + for (uint i = 0; i < hlines; ++i) tty->print_cr(pm_stats_hdr[i]); + for (uint i = 0; i < ParallelGCThreads + 1; ++i) { + manager_array(i)->print_local_stats(i); } } -#endif // PS_PM_STATS +void +PSPromotionManager::reset_stats() { + TaskQueueStats& stats = depth_first() ? + claimed_stack_depth()->stats : claimed_stack_breadth()->stats; + stats.reset(); + _masked_pushes = _masked_steals = 0; + _arrays_chunked = _array_chunks_processed = 0; +} +#endif // TASKQUEUE_STATS PSPromotionManager::PSPromotionManager() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); @@ -189,16 +207,7 @@ _prefetch_queue.clear(); -#if PS_PM_STATS - _total_pushes = 0; - _masked_pushes = 0; - _overflow_pushes = 0; - _max_overflow_length = 0; - _arrays_chunked = 0; - _array_chunks_processed = 0; - _total_steals = 0; - _masked_steals = 0; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(reset_stats()); } @@ -423,14 +432,9 @@ new_obj->is_objArray() && PSChunkLargeArrays) { // we'll chunk it -#if PS_PM_STATS - ++_arrays_chunked; -#endif // PS_PM_STATS oop* const masked_o = mask_chunked_array_oop(o); push_depth(masked_o); -#if PS_PM_STATS - ++_masked_pushes; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(++_arrays_chunked; ++_masked_pushes); } else { // we'll just push its contents new_obj->push_contents(this); @@ -494,9 +498,7 @@ assert(old->is_objArray(), "invariant"); assert(old->is_forwarded(), "invariant"); -#if PS_PM_STATS - ++_array_chunks_processed; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(++_array_chunks_processed); oop const obj = old->forwardee(); @@ -508,9 +510,7 @@ assert(start > 0, "invariant"); arrayOop(old)->set_length(start); push_depth(mask_chunked_array_oop(old)); -#if PS_PM_STATS - ++_masked_pushes; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(++_masked_pushes); } else { // this is the final chunk for this array start = 0;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -42,8 +42,6 @@ class PSOldGen; class ParCompactionManager; -#define PS_PM_STATS 0 - class PSPromotionManager : public CHeapObj { friend class PSScavenge; friend class PSRefProcTaskExecutor; @@ -54,22 +52,18 @@ static PSOldGen* _old_gen; static MutableSpace* _young_space; -#if PS_PM_STATS - uint _total_pushes; - uint _masked_pushes; - - uint _overflow_pushes; - uint _max_overflow_length; +#if TASKQUEUE_STATS + size_t _masked_pushes; + size_t _masked_steals; + size_t _arrays_chunked; + size_t _array_chunks_processed; - uint _arrays_chunked; - uint _array_chunks_processed; + void print_taskqueue_stats(uint i) const; + void print_local_stats(uint i) const; + static void print_stats(); - uint _total_steals; - uint _masked_steals; - - void print_stats(uint i); - static void print_stats(); -#endif // PS_PM_STATS + void reset_stats(); +#endif // TASKQUEUE_STATS PSYoungPromotionLAB _young_lab; PSOldPromotionLAB _old_lab; @@ -143,42 +137,12 @@ template <class T> void push_depth(T* p) { assert(depth_first(), "pre-condition"); - -#if PS_PM_STATS - ++_total_pushes; - int stack_length = claimed_stack_depth()->overflow_stack()->length(); -#endif // PS_PM_STATS - claimed_stack_depth()->push(p); - -#if PS_PM_STATS - if (claimed_stack_depth()->overflow_stack()->length() != stack_length) { - ++_overflow_pushes; - if ((uint)stack_length + 1 > _max_overflow_length) { - _max_overflow_length = (uint)stack_length + 1; - } - } -#endif // PS_PM_STATS } void push_breadth(oop o) { assert(!depth_first(), "pre-condition"); - -#if PS_PM_STATS - ++_total_pushes; - int stack_length = claimed_stack_breadth()->overflow_stack()->length(); -#endif // PS_PM_STATS - claimed_stack_breadth()->push(o); - -#if PS_PM_STATS - if (claimed_stack_breadth()->overflow_stack()->length() != stack_length) { - ++_overflow_pushes; - if ((uint)stack_length + 1 > _max_overflow_length) { - _max_overflow_length = (uint)stack_length + 1; - } - } -#endif // PS_PM_STATS } protected: @@ -256,12 +220,5 @@ template <class T> inline void claim_or_forward_depth(T* p); template <class T> inline void claim_or_forward_breadth(T* p); -#if PS_PM_STATS - void increment_steals(oop* p = NULL) { - _total_steals += 1; - if (p != NULL && is_oop_masked(p)) { - _masked_steals += 1; - } - } -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(inline void record_steal(StarTask& p);) };
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -124,3 +124,11 @@ } } } + +#if TASKQUEUE_STATS +void PSPromotionManager::record_steal(StarTask& p) { + if (is_oop_masked(p)) { + ++_masked_steals; + } +} +#endif // TASKQUEUE_STATS
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -148,9 +148,7 @@ while(true) { StarTask p; if (PSPromotionManager::steal_depth(which, &random_seed, p)) { -#if PS_PM_STATS - pm->increment_steals(p); -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(pm->record_steal(p)); pm->process_popped_location_depth(p); pm->drain_stacks_depth(true); } else { @@ -163,9 +161,6 @@ while(true) { oop obj; if (PSPromotionManager::steal_breadth(which, &random_seed, obj)) { -#if PS_PM_STATS - pm->increment_steals(); -#endif // PS_PM_STATS obj->copy_contents(pm); pm->drain_stacks_breadth(true); } else {
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -86,9 +86,7 @@ _gc_locked = false; - if (full) { - _full_gc_count_before = full_gc_count_before; - } + _full_gc_count_before = full_gc_count_before; // In ParallelScavengeHeap::mem_allocate() collections can be // executed within a loop and _all_soft_refs_clear can be set // true after they have been cleared by a collection and another
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -78,6 +78,9 @@ case _old_generation_too_full_to_scavenge: return "Old Generation Too Full To Scavenge"; + case _g1_inc_collection_pause: + return "G1 Evacuation Pause"; + case _last_ditch_collection: return "Last ditch collection";
--- a/hotspot/src/share/vm/includeDB_compiler1 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/includeDB_compiler1 Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/includeDB_compiler2 Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/includeDB_core Fri Aug 20 14:48:10 2010 -0400 @@ -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 Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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/bytecodeTracer.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -328,24 +328,35 @@ constantPoolOop constants = method()->constants(); constantTag tag = constants->tag_at(i); - int nt_index = -1; + bool has_klass = true; switch (tag.value()) { case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Methodref: case JVM_CONSTANT_Fieldref: + break; case JVM_CONSTANT_NameAndType: + case JVM_CONSTANT_InvokeDynamic: + has_klass = false; break; default: st->print_cr(" bad tag=%d at %d", tag.value(), i); return; } - symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i)); symbolOop name = constants->uncached_name_ref_at(i); symbolOop signature = constants->uncached_signature_ref_at(i); const char* sep = (tag.is_field() ? "/" : ""); - st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string()); + if (has_klass) { + symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i)); + st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string()); + } else { + if (tag.is_invoke_dynamic()) { + int bsm = constants->invoke_dynamic_bootstrap_method_ref_index_at(i); + st->print(" bsm=%d", bsm); + } + st->print_cr(" %d <%s%s%s>", i, name->as_C_string(), sep, signature->as_C_string()); + } }
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreter.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -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 Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreter.hpp Fri Aug 20 14:48:10 2010 -0400 @@ -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/interpreterRuntime.cpp Thu Aug 12 23:21:17 2010 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Fri Aug 20 14:48:10 2010 -0400 @@ -702,10 +702,6 @@ methodHandle caller_method(thread, method(thread)); - // first find the bootstrap method - KlassHandle caller_klass(thread, caller_method->method_holder()); - Handle bootm = SystemDictionary::find_bootstrap_method(caller_klass, CHECK); - constantPoolHandle pool(thread, caller_method->constants()); pool->set_invokedynamic(); // mark header to flag active call sites @@ -726,7 +722,7 @@ CallInfo info; LinkResolver::resolve_invoke(info, Handle(), pool,