Merge
authorlana
Thu, 02 Sep 2010 12:17:21 -0700
changeset 6486 85f30f8aa7f3
parent 6485 5e6b2f2666ae (current diff)
parent 6325 adf468d05745 (diff)
child 6487 d6ad2c68a522
Merge
jdk/src/share/classes/sun/java2d/pisces/PiscesMath.java
jdk/src/share/classes/sun/java2d/pisces/Transform4.java
jdk/test/tools/pack200/Pack200Simple.sh
jdk/test/tools/pack200/SegmentLimit.java
--- a/.hgtags	Tue Aug 31 15:05:09 2010 +0400
+++ b/.hgtags	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
 88db80c8e49cea352c2900f689600dc410761c1f jdk7-b102
 64770970865839b0443066370e7d476ef47e90cd jdk7-b103
 10bc903a228d3a8efdf46fb8c3fcf82a59b88bc5 jdk7-b104
+1ce7938efb03224ccc8b3cdd7803eb39e889539c jdk7-b105
+6bdae472f77205046703b685eff2ac4f7a0ecf4e jdk7-b106
+439de530aac531a360beedba6e2fe51e17292cc0 jdk7-b107
--- a/.hgtags-top-repo	Tue Aug 31 15:05:09 2010 +0400
+++ b/.hgtags-top-repo	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
 a136a51f5113da4dad3853b74a8536ab583ab112 jdk7-b102
 be2aedc4e3b1751c1310f334242ba69e90867f38 jdk7-b103
 f8be576feefce0c6695f188ef97ec16b73ad9cfd jdk7-b104
+9f96a4269d7727dad68864eaab795eafce270311 jdk7-b105
+43096cccf1cee749c2f4e7714ee71f4e9e0f4d7f jdk7-b106
+7d396ad455c3b2f68b0d7094891c5aba7c757a6e jdk7-b107
--- a/corba/.hgtags	Tue Aug 31 15:05:09 2010 +0400
+++ b/corba/.hgtags	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
 78561a95779090b5106c8d0f1a75360a027ef087 jdk7-b102
 11e7678c3eb169b77d9a9892fe5e3dfa1d1a0d51 jdk7-b103
 9607213481d400ac477183191cc080e1bef6f475 jdk7-b104
+6f21b030092fb61244cc8a0aedf8058f7c022b81 jdk7-b105
+519daea48888196af76a975a3b31258efa860bad jdk7-b106
+232adb83eae8375439ccff65b6e205ca0da0510d jdk7-b107
--- a/hotspot/.hgtags	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/.hgtags	Thu Sep 02 12:17:21 2010 -0700
@@ -110,3 +110,8 @@
 cb4250ef73b21de6c487ea14e2b0b99eed67b4b6 jdk7-b103
 e55900b5c1b865cac17e18abc639c7dc50de7fd8 hs19-b04
 b4acf10eb134fe930802c97e36db65e7ccb544b5 jdk7-b104
+6709c14587c2cc6faca208767335afeb01e33de5 jdk7-b105
+1b81ca701fa5fc30adc4cfdaa4bdd153df5e6c86 jdk7-b106
+cc3fdfeb54b049f18edcf3463e6ab051d0b7b609 hs19-b05
+688a538aa65412178286ae2a6b0c00b6711e121b hs19-b06
+bf496cbe9b74dda5975a1559da7ecfdd313e509e jdk7-b107
--- a/hotspot/agent/src/os/linux/ps_proc.c	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/agent/src/os/linux/ps_proc.c	Thu Sep 02 12:17:21 2010 -0700
@@ -253,7 +253,11 @@
     if (nwords > 5 && find_lib(ph, word[5]) == false) {
        intptr_t base;
        lib_info* lib;
+#ifdef _LP64
        sscanf(word[0], "%lx", &base);
+#else
+       sscanf(word[0], "%x", &base);
+#endif
        if ((lib = add_lib_info(ph, word[5], (uintptr_t)base)) == NULL)
           continue; // ignore, add_lib_info prints error
 
--- a/hotspot/make/Makefile	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/Makefile	Thu Sep 02 12:17:21 2010 -0700
@@ -85,14 +85,21 @@
 C2_VM_TARGETS=product  fastdebug  optimized  jvmg
 KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
 ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
+SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark
 
 # JDK directory list
 JDK_DIRS=bin include jre lib demo
 
 all:           all_product all_fastdebug
+ifndef BUILD_CLIENT_ONLY
 all_product:   product product1 productkernel docs export_product
 all_fastdebug: fastdebug fastdebug1 fastdebugkernel docs export_fastdebug
 all_debug:     jvmg jvmg1 jvmgkernel docs export_debug
+else
+all_product:   product1 docs export_product
+all_fastdebug: fastdebug1 docs export_fastdebug
+all_debug:     jvmg1 docs export_debug
+endif
 all_optimized: optimized optimized1 optimizedkernel docs export_optimized
 
 allzero:           all_productzero all_fastdebugzero
@@ -101,6 +108,12 @@
 all_debugzero:     jvmgzero docs export_debug
 all_optimizedzero: optimizedzero docs export_optimized
 
+allshark:           all_productshark all_fastdebugshark
+all_productshark:   productshark docs export_product
+all_fastdebugshark: fastdebugshark docs export_fastdebug
+all_debugshark:     jvmgshark docs export_debug
+all_optimizedshark: optimizedshark docs export_optimized
+
 # Do everything
 world:         all create_jdk
 
@@ -131,6 +144,10 @@
 	$(CD) $(GAMMADIR)/make; \
 	$(MAKE) VM_TARGET=$@ generic_buildzero $(ALT_OUT)
 
+$(SHARK_VM_TARGETS):
+	$(CD) $(GAMMADIR)/make; \
+	$(MAKE) VM_TARGET=$@ generic_buildshark $(ALT_OUT)
+
 # Build compiler1 (client) rule, different for platforms
 generic_build1:
 	$(MKDIR) -p $(OUTPUTDIR)
@@ -197,6 +214,12 @@
 		$(MAKE) -f $(ABS_OS_MAKEFILE) \
 			$(MAKE_ARGS) $(VM_TARGET)
 
+generic_buildshark:
+	$(MKDIR) -p $(OUTPUTDIR)
+	$(CD) $(OUTPUTDIR); \
+		$(MAKE) -f $(ABS_OS_MAKEFILE) \
+			$(MAKE_ARGS) $(VM_TARGET) 
+
 # Export file rule
 generic_export: $(EXPORT_LIST)
 export_product:
@@ -228,15 +251,22 @@
 C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
 KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel
 ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
+SHARK_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_shark
 C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
 C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
 KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
 ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
+SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
 
 # Misc files and generated files need to come from C1 or C2 area
 ifeq ($(ZERO_BUILD), true)
+ifeq ($(SHARK_BUILD), true)
+  MISC_DIR=$(SHARK_DIR)
+  GEN_DIR=$(SHARK_BASE_DIR)/generated
+else
   MISC_DIR=$(ZERO_DIR)
   GEN_DIR=$(ZERO_BASE_DIR)/generated
+endif
 else
 ifeq ($(ARCH_DATA_MODEL), 32)
   MISC_DIR=$(C1_DIR)
@@ -290,11 +320,20 @@
 # Shared Library
 ifneq ($(OSNAME),windows)
   ifeq ($(ZERO_BUILD), true)
+    ifeq ($(SHARK_BUILD), true)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(SHARK_DIR)/%.so
+	$(install-file)
+$(EXPORT_SERVER_DIR)/%.so:       $(SHARK_DIR)/%.so
+	$(install-file)
+    else
 $(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(ZERO_DIR)/%.so
 	$(install-file)
 $(EXPORT_SERVER_DIR)/%.so:       $(ZERO_DIR)/%.so
 	$(install-file)
+    endif
   else
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C1_DIR)/%.so
+	$(install-file)
 $(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C2_DIR)/%.so
 	$(install-file)
 $(EXPORT_CLIENT_DIR)/%.so:       $(C1_DIR)/%.so
@@ -348,6 +387,7 @@
 	$(RM) -r $(C2_DIR)
 	$(RM) -r $(KERNEL_DIR)
 	$(RM) -r $(ZERO_DIR)
+	$(RM) -r $(SHARK_DIR)
 clean_export:
 	$(RM) -r $(EXPORT_PATH)
 clean_jdk:
--- a/hotspot/make/defs.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/defs.make	Thu Sep 02 12:17:21 2010 -0700
@@ -192,13 +192,16 @@
 
   # Use uname output for SRCARCH, but deal with platform differences. If ARCH
   # is not explicitly listed below, it is treated as x86. 
-  SRCARCH     = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 zero,$(ARCH)))
+  SRCARCH     = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc zero,$(ARCH)))
   ARCH/       = x86
   ARCH/sparc  = sparc
   ARCH/sparc64= sparc
   ARCH/ia64   = ia64
   ARCH/amd64  = x86
   ARCH/x86_64 = x86
+  ARCH/ppc64  = ppc
+  ARCH/ppc    = ppc
+  ARCH/arm    = arm
   ARCH/zero   = zero
 
   # BUILDARCH is usually the same as SRCARCH, except for sparcv9
@@ -223,6 +226,9 @@
   LIBARCH/sparc   = sparc
   LIBARCH/sparcv9 = sparcv9
   LIBARCH/ia64    = ia64
+  LIBARCH/ppc64   = ppc
+  LIBARCH/ppc     = ppc
+  LIBARCH/arm     = arm
   LIBARCH/zero    = $(ZERO_LIBARCH)
 
   LP64_ARCH = sparcv9 amd64 ia64 zero
--- a/hotspot/make/hotspot_version	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/hotspot_version	Thu Sep 02 12:17:21 2010 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=19
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=05
+HS_BUILD_NUMBER=06
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/make/linux/Makefile	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/Makefile	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -168,6 +168,13 @@
 #       profiledzero    zero            <os>_<arch>_zero/profiled
 #       productzero     zero            <os>_<arch>_zero/product
 #
+#       debugshark      shark           <os>_<arch>_shark/debug
+#       fastdebugshark  shark           <os>_<arch>_shark/fastdebug
+#       jvmgshark       shark           <os>_<arch>_shark/jvmg
+#       optimizedshark  shark           <os>_<arch>_shark/optimized
+#       profiledshark   shark           <os>_<arch>_shark/profiled
+#       productshark    shark           <os>_<arch>_shark/product
+#
 # What you get with each target:
 #
 # debug*     - "thin" libjvm_g - debug info linked into the gamma_g launcher
@@ -191,12 +198,14 @@
 SUBDIRS_TIERED    = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS))
 SUBDIRS_CORE      = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
 SUBDIRS_ZERO      = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS))
+SUBDIRS_SHARK     = $(addprefix $(OSNAME)_$(VARIANTARCH)_shark/,$(TARGETS))
 
 TARGETS_C2        = $(TARGETS)
 TARGETS_C1        = $(addsuffix 1,$(TARGETS))
 TARGETS_TIERED    = $(addsuffix tiered,$(TARGETS))
 TARGETS_CORE      = $(addsuffix core,$(TARGETS))
 TARGETS_ZERO      = $(addsuffix zero,$(TARGETS))
+TARGETS_SHARK     = $(addsuffix shark,$(TARGETS))
 
 BUILDTREE_MAKE    = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
 BUILDTREE_VARS    = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
@@ -213,6 +222,7 @@
 	@echo "  $(TARGETS_C1)"
 	@echo "  $(TARGETS_CORE)"
 	@echo "  $(TARGETS_ZERO)"
+	@echo "  $(TARGETS_SHARK)"
 
 checks: check_os_version check_j2se_version
 
@@ -266,6 +276,10 @@
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
 	$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
 
+$(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero
+	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
+	$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
+
 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
 	$(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
 
@@ -306,11 +320,19 @@
 	cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
+$(TARGETS_SHARK):  $(SUBDIRS_SHARK)
+	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS)
+	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma
+ifdef INSTALL
+	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install
+endif
+
 # Just build the tree, and nothing else:
 tree:      $(SUBDIRS_C2)
 tree1:     $(SUBDIRS_C1)
 treecore:  $(SUBDIRS_CORE)
 treezero:  $(SUBDIRS_ZERO)
+treeshark: $(SUBDIRS_SHARK)
 
 # Doc target.  This is the same for all build options.
 #     Hence create a docs directory beside ...$(ARCH)_[...]
@@ -327,20 +349,22 @@
 
 zero: jvmgzero productzero
 
+shark: jvmgshark productshark
+
 clean_docs:
 	rm -rf $(SUBDIR_DOCS)
 
-clean_compiler1 clean_compiler2 clean_core clean_zero:
+clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark:
 	rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@)
 
-clean:  clean_compiler2 clean_compiler1 clean_core clean_zero clean_docs
+clean:  clean_compiler2 clean_compiler1 clean_core clean_zero clean_shark clean_docs
 
 include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make
 
 #-------------------------------------------------------------------------------
 
-.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO)
-.PHONY: tree tree1 treecore treezero
-.PHONY: all compiler1 compiler2 core zero
-.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero docs clean_docs
+.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK)
+.PHONY: tree tree1 treecore treezero treeshark
+.PHONY: all compiler1 compiler2 core zero shark
+.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
 .PHONY: checks check_os_version check_j2se_version
--- a/hotspot/make/linux/makefiles/build_vm_def.sh	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/build_vm_def.sh	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,12 @@
 #!/bin/sh
 
-nm --defined-only $* | awk '
+# If we're cross compiling use that path for nm
+if [ "$ALT_COMPILER_PATH" != "" ]; then 
+NM=$ALT_COMPILER_PATH/nm
+else
+NM=nm
+fi
+
+$NM --defined-only $* | awk '
    { if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";" }
    '
--- a/hotspot/make/linux/makefiles/buildtree.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/buildtree.make	Thu Sep 02 12:17:21 2010 -0700
@@ -339,12 +339,16 @@
 WRONG_DATA_MODE_MSG = \
 	echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
 
+CROSS_COMPILING_MSG = \
+	echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
+
 test_gamma:  $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	echo '#!/bin/sh'; \
 	$(BUILDTREE_COMMENT); \
 	echo '. ./env.sh'; \
+	echo "if [ \"$(CROSS_COMPILE_ARCH)\" != \"\" ]; then { $(CROSS_COMPILING_MSG); exit 0; }; fi"; \
 	echo "if [ -z \$$JAVA_HOME ]; then { $(NO_JAVA_HOME_MSG); exit 0; }; fi"; \
 	echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>&1 > /dev/null"; \
 	echo "then"; \
--- a/hotspot/make/linux/makefiles/defs.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/defs.make	Thu Sep 02 12:17:21 2010 -0700
@@ -98,6 +98,22 @@
   HS_ARCH          = x86
 endif
 
+# ARM
+ifeq ($(ARCH), arm)
+  ARCH_DATA_MODEL  = 32
+  PLATFORM         = linux-arm
+  VM_PLATFORM      = linux_arm
+  HS_ARCH          = arm
+endif
+
+# PPC
+ifeq ($(ARCH), ppc)
+  ARCH_DATA_MODEL  = 32
+  PLATFORM         = linux-ppc
+  VM_PLATFORM      = linux_ppc
+  HS_ARCH          = ppc
+endif
+
 JDK_INCLUDE_SUBDIR=linux
 
 # FIXUP: The subdirectory for a debug build is NOT the same on all platforms
@@ -107,22 +123,32 @@
 
 # client and server subdirectories have symbolic links to ../libjsig.so
 EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
+EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
 
-EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
+ifndef BUILD_CLIENT_ONLY
 EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
 EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
+endif
+
 ifneq ($(ZERO_BUILD), true)
   ifeq ($(ARCH_DATA_MODEL), 32)
     EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
     EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
     EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so 
-    EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
-    EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar 
-  else
-    ifeq ($(ARCH),ia64)
-      else
-        EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
-        EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
-    endif
   endif
 endif
+
+# Serviceability Binaries
+# No SA Support for PPC, IA64, ARM or zero
+ADD_SA_BINARIES/x86   = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so \
+                        $(EXPORT_LIB_DIR)/sa-jdi.jar 
+ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so \
+                        $(EXPORT_LIB_DIR)/sa-jdi.jar 
+ADD_SA_BINARIES/ppc   = 
+ADD_SA_BINARIES/ia64  = 
+ADD_SA_BINARIES/arm   = 
+ADD_SA_BINARIES/zero  = 
+
+EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH))
+
+
--- a/hotspot/make/linux/makefiles/gcc.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/gcc.make	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,14 @@
 #------------------------------------------------------------------------
 # CC, CPP & AS
 
+ifdef ALT_COMPILER_PATH
+CPP = $(ALT_COMPILER_PATH)/g++
+CC  = $(ALT_COMPILER_PATH)/gcc
+else
 CPP = g++
 CC  = gcc
+endif
+
 AS  = $(CC) -c
 
 # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
@@ -55,6 +61,9 @@
 ifeq ($(ZERO_BUILD), true)
 CFLAGS += $(LIBFFI_CFLAGS)
 endif
+ifeq ($(SHARK_BUILD), true)
+CFLAGS += $(LLVM_CFLAGS)
+endif
 CFLAGS += $(VM_PICFLAG)
 CFLAGS += -fno-rtti
 CFLAGS += -fno-exceptions
@@ -67,18 +76,31 @@
 ARCHFLAG/ia64    =
 ARCHFLAG/sparc   = -m32 -mcpu=v9
 ARCHFLAG/sparcv9 = -m64 -mcpu=v9
+ARCHFLAG/arm     =  -fsigned-char
 ARCHFLAG/zero    = $(ZERO_ARCHFLAG)
+ifndef E500V2
+ARCHFLAG/ppc     =  -mcpu=powerpc
+endif
 
 CFLAGS     += $(ARCHFLAG)
 AOUT_FLAGS += $(ARCHFLAG)
 LFLAGS     += $(ARCHFLAG)
 ASFLAGS    += $(ARCHFLAG)
 
+ifdef E500V2
+CFLAGS += -DE500V2
+endif
+
 # Use C++ Interpreter
 ifdef CC_INTERP
   CFLAGS += -DCC_INTERP
 endif
 
+# Build for embedded targets
+ifdef JAVASE_EMBEDDED
+  CFLAGS += -DJAVASE_EMBEDDED
+endif
+
 # Keep temporary files (.ii, .s)
 ifdef NEED_ASM
   CFLAGS += -save-temps
@@ -171,6 +193,8 @@
 # Note: The Itanium gcc compiler crashes when using -gstabs.
 DEBUG_CFLAGS/ia64  = -g
 DEBUG_CFLAGS/amd64 = -g
+DEBUG_CFLAGS/arm   = -g
+DEBUG_CFLAGS/ppc   = -g
 DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
 ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
 DEBUG_CFLAGS += -gstabs
@@ -181,3 +205,15 @@
   DEBUG_CFLAGS = -g
   CFLAGS += $(DEBUG_CFLAGS)
 endif
+
+# If we are building HEADLESS, pass on to VM
+# so it can set the java.awt.headless property
+ifdef HEADLESS
+CFLAGS += -DHEADLESS
+endif
+
+# We are building Embedded for a small device
+# favor code space over speed
+ifdef MINIMIZE_RAM_USAGE
+CFLAGS += -DMINIMIZE_RAM_USAGE
+endif
--- a/hotspot/make/linux/makefiles/product.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/product.make	Thu Sep 02 12:17:21 2010 -0700
@@ -46,7 +46,11 @@
 
 # use -g to strip library as -x will discard its symbol table; -x is fine for
 # executables.
-STRIP = strip
+ifdef CROSS_COMPILE_ARCH
+  STRIP = $(ALT_COMPILER_PATH)/strip
+else
+  STRIP = strip
+endif
 STRIP_LIBJVM = $(STRIP) -g $@ || exit 1;
 STRIP_AOUT   = $(STRIP) -x $@ || exit 1;
 
--- a/hotspot/make/linux/makefiles/sa.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/sa.make	Thu Sep 02 12:17:21 2010 -0700
@@ -55,10 +55,13 @@
 SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
 
 # if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium or zero.
+# also, we don't build SA on Itanium, PowerPC, ARM or zero.
 
 all: 
-	if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \
+	if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" \
+             -a "$(SRCARCH)" != "arm" \
+             -a "$(SRCARCH)" != "ppc" \
+             -a "$(SRCARCH)" != "zero" ] ; then \
 	   $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
 	fi
 
--- a/hotspot/make/linux/makefiles/saproc.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/saproc.make	Thu Sep 02 12:17:21 2010 -0700
@@ -53,10 +53,10 @@
 endif
 
 # if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium or zero.
+# also, we don't build SA on Itanium, PPC, ARM or zero.
 
 checkAndBuildSA:
-	$(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \
+	$(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "arm" -a "$(SRCARCH)" != "ppc" -a "$(SRCARCH)" != "zero" ] ; then \
 	   $(MAKE) -f vm.make $(LIBSAPROC); \
 	fi
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/linux/makefiles/shark.make	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2008, 2010 Red Hat, Inc.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#  
+#
+
+# Sets make macros for making Shark version of VM
+
+TYPE = SHARK
+
+VM_SUBDIR = server
+
+CFLAGS += -DSHARK
--- a/hotspot/make/linux/makefiles/top.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/top.make	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,7 @@
 Include_DBs/COMPILER2   = $(Include_DBs/CORE) $(VM)/includeDB_compiler2
 Include_DBs/TIERED      = $(Include_DBs/CORE) $(VM)/includeDB_compiler1 $(VM)/includeDB_compiler2
 Include_DBs/ZERO        = $(Include_DBs/CORE) $(VM)/includeDB_zero
+Include_DBs/SHARK       = $(Include_DBs/ZERO) $(VM)/includeDB_shark
 Include_DBs = $(Include_DBs/$(TYPE))
 
 Cached_plat = $(GENERATED)/platform.current
--- a/hotspot/make/linux/makefiles/vm.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/linux/makefiles/vm.make	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -98,6 +98,7 @@
 
 # Extra flags from gnumake's invocation or environment
 CFLAGS += $(EXTRA_CFLAGS)
+LFLAGS += $(EXTRA_CFLAGS)
 
 LIBS += -lm -ldl -lpthread
 
@@ -136,10 +137,14 @@
 vm.def: $(Res_Files) $(Obj_Files)
 	sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
 
-ifeq ($(ZERO_LIBARCH), ppc64)
+ifeq ($(SHARK_BUILD), true)
   STATIC_CXX = false
 else
-  STATIC_CXX = true
+  ifeq ($(ZERO_LIBARCH), ppc64)
+    STATIC_CXX = false
+  else
+    STATIC_CXX = true
+  endif
 endif
 
 ifeq ($(LINK_INTO),AOUT)
@@ -167,6 +172,10 @@
 ifeq ($(ZERO_BUILD), true)
   LIBS_VM += $(LIBFFI_LIBS)
 endif
+ifeq ($(SHARK_BUILD), true)
+  LFLAGS_VM += $(LLVM_LDFLAGS)
+  LIBS_VM   += $(LLVM_LIBS)
+endif
 
 LINK_VM = $(LINK_LIB.c)
 
@@ -210,15 +219,17 @@
 	    $(LINK_LIB.CC/POST_HOOK)                                    \
 	    rm -f $@.1; ln -s $@ $@.1;                                  \
 	    [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
-	    if [ -x /usr/sbin/selinuxenabled ] ; then                   \
-	      /usr/sbin/selinuxenabled;                                 \
-              if [ $$? = 0 ] ; then					\
-		/usr/bin/chcon -t textrel_shlib_t $@;                   \
-		if [ $$? != 0 ]; then                                   \
-		  echo "ERROR: Cannot chcon $@";			\
-		fi							\
-	      fi							\
-	    fi                                                          \
+            if [ \"$(CROSS_COMPILE_ARCH)\" = \"\" ] ; then                    \
+	      if [ -x /usr/sbin/selinuxenabled ] ; then                 \
+	        /usr/sbin/selinuxenabled;                               \
+                if [ $$? = 0 ] ; then					\
+		  /usr/bin/chcon -t textrel_shlib_t $@;                 \
+		  if [ $$? != 0 ]; then                                 \
+		    echo "ERROR: Cannot chcon $@";			\
+		  fi							\
+	        fi							\
+	      fi                                                        \
+            fi 								\
 	}
 
 DEST_JVM = $(JDK_LIBDIR)/$(VM_SUBDIR)/$(LIBJVM)
--- a/hotspot/make/solaris/makefiles/defs.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/solaris/makefiles/defs.make	Thu Sep 02 12:17:21 2010 -0700
@@ -70,20 +70,24 @@
 EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
 
 EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
+ifneq ($(BUILD_CLIENT_ONLY),true)
 EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
 EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
 EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.so
 EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so
+endif
 ifeq ($(ARCH_DATA_MODEL), 32)
   EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so 
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so 
-  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so 
-  EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.so
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.so
-  EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.so
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.so
+  ifneq ($(BUILD_CLIENT_ONLY), true)
+    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.so
+    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.so
+  endif
 endif
 
 EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
--- a/hotspot/make/solaris/makefiles/sparcWorks.make	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/make/solaris/makefiles/sparcWorks.make	Thu Sep 02 12:17:21 2010 -0700
@@ -145,11 +145,20 @@
 OPT_CFLAGS/O2=-xO2
 OPT_CFLAGS/NOOPT=-xO1
 
+#################################################
+# Begin current (>=5.9) Forte compiler options #
+#################################################
+
 ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
 ifeq ($(Platform_arch), x86)
 OPT_CFLAGS/NO_TAIL_CALL_OPT  = -Wu,-O~yz
 OPT_CCFLAGS/NO_TAIL_CALL_OPT = -Qoption ube -O~yz
+OPT_CFLAGS/stubGenerator_x86_32.o = $(OPT_CFLAGS) -xspace
+OPT_CFLAGS/stubGenerator_x86_64.o = $(OPT_CFLAGS) -xspace
 endif # Platform_arch == x86
+ifeq ("${Platform_arch}", "sparc")
+OPT_CFLAGS/stubGenerator_sparc.o = $(OPT_CFLAGS) -xspace
+endif
 endif # COMPILER_REV_NUMERIC >= 509
 
 #################################################
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -626,7 +626,7 @@
 }
 
 // This code sequence is relocatable to any address, even on LP64.
-void MacroAssembler::jumpl(AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line) {
+void MacroAssembler::jumpl(const AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line) {
   assert_not_delayed();
   // Force fixed length sethi because NativeJump and NativeFarCall don't handle
   // variable length instruction streams.
@@ -672,7 +672,7 @@
   }
 }
 
-void MacroAssembler::jump(AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) {
+void MacroAssembler::jump(const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) {
   jumpl(addrlit, temp, G0, offset, file, line);
 }
 
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1974,12 +1974,12 @@
 
   // address pseudos: make these names unlike instruction names to avoid confusion
   inline intptr_t load_pc_address( Register reg, int bytes_to_skip );
-  inline void load_contents(AddressLiteral& addrlit, Register d, int offset = 0);
-  inline void load_ptr_contents(AddressLiteral& addrlit, Register d, int offset = 0);
-  inline void store_contents(Register s, AddressLiteral& addrlit, Register temp, int offset = 0);
-  inline void store_ptr_contents(Register s, AddressLiteral& addrlit, Register temp, int offset = 0);
-  inline void jumpl_to(AddressLiteral& addrlit, Register temp, Register d, int offset = 0);
-  inline void jump_to(AddressLiteral& addrlit, Register temp, int offset = 0);
+  inline void load_contents(const AddressLiteral& addrlit, Register d, int offset = 0);
+  inline void load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset = 0);
+  inline void store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0);
+  inline void store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0);
+  inline void jumpl_to(const AddressLiteral& addrlit, Register temp, Register d, int offset = 0);
+  inline void jump_to(const AddressLiteral& addrlit, Register temp, int offset = 0);
   inline void jump_indirect_to(Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0);
 
   // ring buffer traceable jumps
@@ -1987,8 +1987,8 @@
   void jmp2( Register r1, Register r2, const char* file, int line );
   void jmp ( Register r1, int offset,  const char* file, int line );
 
-  void jumpl(AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line);
-  void jump (AddressLiteral& addrlit, Register temp,             int offset, const char* file, int line);
+  void jumpl(const AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line);
+  void jump (const AddressLiteral& addrlit, Register temp,             int offset, const char* file, int line);
 
 
   // argument pseudos:
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -650,28 +650,28 @@
 }
 
 
-inline void MacroAssembler::load_contents(AddressLiteral& addrlit, Register d, int offset) {
+inline void MacroAssembler::load_contents(const AddressLiteral& addrlit, Register d, int offset) {
   assert_not_delayed();
   sethi(addrlit, d);
   ld(d, addrlit.low10() + offset, d);
 }
 
 
-inline void MacroAssembler::load_ptr_contents(AddressLiteral& addrlit, Register d, int offset) {
+inline void MacroAssembler::load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset) {
   assert_not_delayed();
   sethi(addrlit, d);
   ld_ptr(d, addrlit.low10() + offset, d);
 }
 
 
-inline void MacroAssembler::store_contents(Register s, AddressLiteral& addrlit, Register temp, int offset) {
+inline void MacroAssembler::store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) {
   assert_not_delayed();
   sethi(addrlit, temp);
   st(s, temp, addrlit.low10() + offset);
 }
 
 
-inline void MacroAssembler::store_ptr_contents(Register s, AddressLiteral& addrlit, Register temp, int offset) {
+inline void MacroAssembler::store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) {
   assert_not_delayed();
   sethi(addrlit, temp);
   st_ptr(s, temp, addrlit.low10() + offset);
@@ -679,7 +679,7 @@
 
 
 // This code sequence is relocatable to any address, even on LP64.
-inline void MacroAssembler::jumpl_to(AddressLiteral& addrlit, Register temp, Register d, int offset) {
+inline void MacroAssembler::jumpl_to(const AddressLiteral& addrlit, Register temp, Register d, int offset) {
   assert_not_delayed();
   // Force fixed length sethi because NativeJump and NativeFarCall don't handle
   // variable length instruction streams.
@@ -688,7 +688,7 @@
 }
 
 
-inline void MacroAssembler::jump_to(AddressLiteral& addrlit, Register temp, int offset) {
+inline void MacroAssembler::jump_to(const AddressLiteral& addrlit, Register temp, int offset) {
   jumpl_to(addrlit, temp, G0, offset);
 }
 
--- a/hotspot/src/cpu/sparc/vm/bytecodeInterpreter_sparc.inline.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/bytecodeInterpreter_sparc.inline.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -236,19 +236,19 @@
 }
 
 inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) {
-  return op1 <<  op2;
+  return op1 << (op2 & 0x1f);
 }
 
 inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) {
-  return op1 >>  op2; // QQ op2 & 0x1f??
+  return op1 >> (op2 & 0x1f);
 }
 
 inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) {
   return op1 - op2;
 }
 
-inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
-  return ((juint) op1) >> op2; // QQ op2 & 0x1f??
+inline juint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
+  return ((juint) op1) >> (op2 & 0x1f);
 }
 
 inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -409,7 +409,7 @@
   LIR_Opr lock      = FrameMap::G1_opr;
   LIR_Opr hdr       = FrameMap::G3_opr;
   LIR_Opr obj_temp  = FrameMap::G4_opr;
-  monitor_exit(obj_temp, lock, hdr, x->monitor_no());
+  monitor_exit(obj_temp, lock, hdr, LIR_OprFact::illegalOpr, x->monitor_no());
 }
 
 
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1031,3 +1031,7 @@
 #undef __
 
 #define __ masm->
+
+const char *Runtime1::pd_name_for_address(address entry) {
+  return "<unknown function>";
+}
--- a/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -56,14 +56,18 @@
 }
 
 
-#ifdef _LP64
 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
   Argument  jni_arg(jni_offset(), false);
+#ifdef _LP64
   FloatRegister  Rtmp = F0;
   __ ldf(FloatRegisterImpl::S, Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
   __ store_float_argument(Rtmp, jni_arg);
+#else
+  Register     Rtmp = O0;
+  __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
+  __ store_argument(Rtmp, jni_arg);
+#endif
 }
-#endif
 
 
 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
@@ -185,6 +189,13 @@
     _from -= 2*Interpreter::stackElementSize;
     add_signature( non_float );
   }
+
+  virtual void pass_float() {
+    *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
+    _from -= Interpreter::stackElementSize;
+    add_signature( non_float );
+  }
+
 #endif // _LP64
 
   virtual void add_signature( intptr_t sig_type ) {
--- a/hotspot/src/cpu/sparc/vm/javaFrameAnchor_sparc.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/javaFrameAnchor_sparc.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -76,6 +76,8 @@
 
   void set_last_Java_sp(intptr_t* sp)            { _last_Java_sp = sp; }
 
+  address last_Java_pc(void)                     { return _last_Java_pc; }
+
   // These are only used by friends
 private:
 
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -3236,12 +3236,14 @@
   __ get_2_byte_integer_at_bcp(1, Rscratch, Roffset, InterpreterMacroAssembler::Unsigned);
   __ get_cpool_and_tags(Rscratch, G3_scratch);
   // make sure the class we're about to instantiate has been resolved
+  // This is done before loading instanceKlass to be consistent with the order
+  // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put)
   __ add(G3_scratch, typeArrayOopDesc::header_size(T_BYTE) * wordSize, G3_scratch);
   __ ldub(G3_scratch, Roffset, G3_scratch);
   __ cmp(G3_scratch, JVM_CONSTANT_Class);
   __ br(Assembler::notEqual, false, Assembler::pn, slow_case);
   __ delayed()->sll(Roffset, LogBytesPerWord, Roffset);
-
+  // get instanceKlass
   //__ sll(Roffset, LogBytesPerWord, Roffset);        // executed in delay slot
   __ add(Roffset, sizeof(constantPoolOopDesc), Roffset);
   __ ld_ptr(Rscratch, Roffset, RinstanceKlass);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -7151,7 +7151,7 @@
   subptr(t1, typeArrayOopDesc::header_size(T_INT));
   addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
   shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint)));
-  movptr(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
+  movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
   // set klass to intArrayKlass
   // dubious reloc why not an oop reloc?
   movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
@@ -7568,21 +7568,27 @@
 
   // Scan RCX words at [RDI] for an occurrence of RAX.
   // Set NZ/Z based on last compare.
+  // Z flag value will not be set by 'repne' if RCX == 0 since 'repne' does
+  // not change flags (only scas instruction which is repeated sets flags).
+  // Set Z = 0 (not equal) before 'repne' to indicate that class was not found.
 #ifdef _LP64
   // This part is tricky, as values in supers array could be 32 or 64 bit wide
   // and we store values in objArrays always encoded, thus we need to encode
   // the value of rax before repne.  Note that rax is dead after the repne.
   if (UseCompressedOops) {
-    encode_heap_oop_not_null(rax);
+    encode_heap_oop_not_null(rax); // Changes flags.
     // The superclass is never null; it would be a basic system error if a null
     // pointer were to sneak in here.  Note that we have already loaded the
     // Klass::super_check_offset from the super_klass in the fast path,
     // so if there is a null in that register, we are already in the afterlife.
+    testl(rax,rax); // Set Z = 0
     repne_scanl();
   } else
 #endif // _LP64
+  {
+    testptr(rax,rax); // Set Z = 0
     repne_scan();
-
+  }
   // Unspill the temp. registers:
   if (pushed_rdi)  pop(rdi);
   if (pushed_rcx)  pop(rcx);
@@ -8257,30 +8263,35 @@
   }
 }
 
+#ifdef ASSERT
+void MacroAssembler::verify_heapbase(const char* msg) {
+  assert (UseCompressedOops, "should be compressed");
+  assert (Universe::heap() != NULL, "java heap should be initialized");
+  if (CheckCompressedOops) {
+    Label ok;
+    push(rscratch1); // cmpptr trashes rscratch1
+    cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
+    jcc(Assembler::equal, ok);
+    stop(msg);
+    bind(ok);
+    pop(rscratch1);
+  }
+}
+#endif
+
 // Algorithm must match oop.inline.hpp encode_heap_oop.
 void MacroAssembler::encode_heap_oop(Register r) {
-  assert (UseCompressedOops, "should be compressed");
-  assert (Universe::heap() != NULL, "java heap should be initialized");
+#ifdef ASSERT
+  verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
+#endif
+  verify_oop(r, "broken oop in encode_heap_oop");
   if (Universe::narrow_oop_base() == NULL) {
-    verify_oop(r, "broken oop in encode_heap_oop");
     if (Universe::narrow_oop_shift() != 0) {
       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
       shrq(r, LogMinObjAlignmentInBytes);
     }
     return;
   }
-#ifdef ASSERT
-  if (CheckCompressedOops) {
-    Label ok;
-    push(rscratch1); // cmpptr trashes rscratch1
-    cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
-    jcc(Assembler::equal, ok);
-    stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
-    bind(ok);
-    pop(rscratch1);
-  }
-#endif
-  verify_oop(r, "broken oop in encode_heap_oop");
   testq(r, r);
   cmovq(Assembler::equal, r, r12_heapbase);
   subq(r, r12_heapbase);
@@ -8288,9 +8299,8 @@
 }
 
 void MacroAssembler::encode_heap_oop_not_null(Register r) {
-  assert (UseCompressedOops, "should be compressed");
-  assert (Universe::heap() != NULL, "java heap should be initialized");
 #ifdef ASSERT
+  verify_heapbase("MacroAssembler::encode_heap_oop_not_null: heap base corrupted?");
   if (CheckCompressedOops) {
     Label ok;
     testq(r, r);
@@ -8310,9 +8320,8 @@
 }
 
 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
-  assert (UseCompressedOops, "should be compressed");
-  assert (Universe::heap() != NULL, "java heap should be initialized");
 #ifdef ASSERT
+  verify_heapbase("MacroAssembler::encode_heap_oop_not_null2: heap base corrupted?");
   if (CheckCompressedOops) {
     Label ok;
     testq(src, src);
@@ -8335,40 +8344,21 @@
 }
 
 void  MacroAssembler::decode_heap_oop(Register r) {
-  assert (UseCompressedOops, "should be compressed");
-  assert (Universe::heap() != NULL, "java heap should be initialized");
+#ifdef ASSERT
+  verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
+#endif
   if (Universe::narrow_oop_base() == NULL) {
     if (Universe::narrow_oop_shift() != 0) {
       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
       shlq(r, LogMinObjAlignmentInBytes);
     }
-    verify_oop(r, "broken oop in decode_heap_oop");
-    return;
-  }
-#ifdef ASSERT
-  if (CheckCompressedOops) {
-    Label ok;
-    push(rscratch1);
-    cmpptr(r12_heapbase,
-           ExternalAddress((address)Universe::narrow_oop_base_addr()));
-    jcc(Assembler::equal, ok);
-    stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
-    bind(ok);
-    pop(rscratch1);
-  }
-#endif
-
-  Label done;
-  shlq(r, LogMinObjAlignmentInBytes);
-  jccb(Assembler::equal, done);
-  addq(r, r12_heapbase);
-#if 0
-   // alternate decoding probably a wash.
-   testq(r, r);
-   jccb(Assembler::equal, done);
-   leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
-#endif
-  bind(done);
+  } else {
+    Label done;
+    shlq(r, LogMinObjAlignmentInBytes);
+    jccb(Assembler::equal, done);
+    addq(r, r12_heapbase);
+    bind(done);
+  }
   verify_oop(r, "broken oop in decode_heap_oop");
 }
 
@@ -8410,9 +8400,11 @@
         addq(dst, r12_heapbase);
       }
     }
-  } else if (dst != src) {
+  } else {
     assert (Universe::narrow_oop_base() == NULL, "sanity");
-    movq(dst, src);
+    if (dst != src) {
+      movq(dst, src);
+    }
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1714,6 +1714,9 @@
 
   // if heap base register is used - reinit it with the correct value
   void reinit_heapbase();
+
+  DEBUG_ONLY(void verify_heapbase(const char* msg);)
+
 #endif // _LP64
 
   // Int division/remainder for Java
--- a/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -236,11 +236,11 @@
 }
 
 inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) {
-  return op1 <<  op2;
+  return op1 << op2;
 }
 
 inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) {
-  return op1 >>  op2; // QQ op2 & 0x1f??
+  return op1 >> (op2 & 0x1f);
 }
 
 inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) {
@@ -248,7 +248,7 @@
 }
 
 inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
-  return ((juint) op1) >> op2; // QQ op2 & 0x1f??
+  return ((juint) op1) >> (op2 & 0x1f);
 }
 
 inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -349,7 +349,7 @@
   LIR_Opr lock = new_register(T_INT);
   LIR_Opr obj_temp = new_register(T_INT);
   set_no_result(x);
-  monitor_exit(obj_temp, lock, syncTempOpr(), x->monitor_no());
+  monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no());
 }
 
 
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1779,3 +1779,7 @@
 }
 
 #undef __
+
+const char *Runtime1::pd_name_for_address(address entry) {
+  return "<unknown function>";
+}
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -575,8 +575,8 @@
 
 BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
 #ifdef CC_INTERP
-  // Needed for JVMTI. The result should always be in the interpreterState object
-  assert(false, "NYI");
+  // Needed for JVMTI. The result should always be in the
+  // interpreterState object
   interpreterState istate = get_interpreterState();
 #endif // CC_INTERP
   assert(is_interpreted_frame(), "interpreted frame expected");
--- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -34,6 +34,10 @@
   move(offset(), jni_offset() + 1);
 }
 
+void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
+  move(offset(), jni_offset() + 1);
+}
+
 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
    move(offset(), jni_offset() + 2);
    move(offset() + 1, jni_offset() + 1);
@@ -91,6 +95,11 @@
     _from -= Interpreter::stackElementSize;
   }
 
+  virtual void pass_float() {
+    *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
+    _from -= Interpreter::stackElementSize;
+  }
+
   virtual void pass_long() {
     _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
     _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
--- a/hotspot/src/cpu/x86/vm/javaFrameAnchor_x86.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/javaFrameAnchor_x86.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -66,6 +66,8 @@
 
   intptr_t* last_Java_sp(void) const             { return _last_Java_sp; }
 
+  address last_Java_pc(void)                     { return _last_Java_pc; }
+
 private:
 
   static ByteSize last_Java_fp_offset()          { return byte_offset_of(JavaFrameAnchor, _last_Java_fp); }
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -3112,22 +3112,25 @@
   transition(vtos, atos);
   __ get_unsigned_2_byte_index_at_bcp(rdx, 1);
   Label slow_case;
+  Label slow_case_no_pop;
   Label done;
   Label initialize_header;
   Label initialize_object;  // including clearing the fields
   Label allocate_shared;
 
   __ get_cpool_and_tags(rcx, rax);
+
+  // Make sure the class we're about to instantiate has been resolved.
+  // This is done before loading instanceKlass to be consistent with the order
+  // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put)
+  const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize;
+  __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class);
+  __ jcc(Assembler::notEqual, slow_case_no_pop);
+
   // get instanceKlass
   __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc)));
   __ push(rcx);  // save the contexts of klass for initializing the header
 
-  // make sure the class we're about to instantiate has been resolved.
-  // Note: slow_case does a pop of stack, which is why we loaded class/pushed above
-  const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize;
-  __ cmpb(Address(rax, rdx, Address::times_1, tags_offset), JVM_CONSTANT_Class);
-  __ jcc(Assembler::notEqual, slow_case);
-
   // make sure klass is initialized & doesn't have finalizer
   // make sure klass is fully initialized
   __ cmpl(Address(rcx, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized);
@@ -3255,6 +3258,7 @@
   // slow case
   __ bind(slow_case);
   __ pop(rcx);   // restore stack pointer to what it was when we came in.
+  __ bind(slow_case_no_pop);
   __ get_constant_pool(rax);
   __ get_unsigned_2_byte_index_at_bcp(rdx, 1);
   call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), rax, rdx);
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -3126,18 +3126,18 @@
   Label allocate_shared;
 
   __ get_cpool_and_tags(rsi, rax);
-  // get instanceKlass
-  __ movptr(rsi, Address(rsi, rdx,
-                         Address::times_8, sizeof(constantPoolOopDesc)));
-
-  // make sure the class we're about to instantiate has been
-  // resolved. Note: slow_case does a pop of stack, which is why we
-  // loaded class/pushed above
+  // Make sure the class we're about to instantiate has been resolved.
+  // This is done before loading instanceKlass to be consistent with the order
+  // how Constant Pool is updated (see constantPoolOopDesc::klass_at_put)
   const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize;
   __ cmpb(Address(rax, rdx, Address::times_1, tags_offset),
           JVM_CONSTANT_Class);
   __ jcc(Assembler::notEqual, slow_case);
 
+  // get instanceKlass
+  __ movptr(rsi, Address(rsi, rdx,
+            Address::times_8, sizeof(constantPoolOopDesc)));
+
   // make sure klass is initialized & doesn't have finalizer
   // make sure klass is fully initialized
   __ cmpl(Address(rsi,
--- a/hotspot/src/cpu/zero/vm/disassembler_zero.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/cpu/zero/vm/disassembler_zero.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007 Red Hat, Inc.
+ * Copyright 2007, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,13 +23,10 @@
  *
  */
 
-// The disassembler prints out zero code annotated
-// with Java specific information.
-
   static int pd_instruction_alignment() {
-    ShouldNotCallThis();
+    return 1;
   }
 
   static const char* pd_cpu_opts() {
-    ShouldNotCallThis();
+    return "";
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// Set the default values for platform dependent flags used by the
+// Shark compiler.  See globals.hpp for details of what they do.
+
+define_pd_global(bool,     BackgroundCompilation,        true );
+define_pd_global(bool,     UseTLAB,                      true );
+define_pd_global(bool,     ResizeTLAB,                   true );
+define_pd_global(bool,     InlineIntrinsics,             false);
+define_pd_global(bool,     PreferInterpreterNativeStubs, false);
+define_pd_global(bool,     ProfileTraps,                 false);
+define_pd_global(bool,     UseOnStackReplacement,        true );
+define_pd_global(bool,     TieredCompilation,            false);
+
+define_pd_global(intx,     CompileThreshold,             1500);
+define_pd_global(intx,     Tier2CompileThreshold,        1500);
+define_pd_global(intx,     Tier3CompileThreshold,        2500);
+define_pd_global(intx,     Tier4CompileThreshold,        4500);
+
+define_pd_global(intx,     BackEdgeThreshold,            100000);
+define_pd_global(intx,     Tier2BackEdgeThreshold,       100000);
+define_pd_global(intx,     Tier3BackEdgeThreshold,       100000);
+define_pd_global(intx,     Tier4BackEdgeThreshold,       100000);
+
+define_pd_global(intx,     OnStackReplacePercentage,     933  );
+define_pd_global(intx,     FreqInlineSize,               325  );
+define_pd_global(intx,     InlineSmallCode,              1000 );
+define_pd_global(intx,     NewRatio,                     12   );
+define_pd_global(intx,     NewSizeThreadIncrease,        4*K  );
+define_pd_global(intx,     InitialCodeCacheSize,         160*K);
+define_pd_global(intx,     ReservedCodeCacheSize,        32*M );
+define_pd_global(bool,     ProfileInterpreter,           false);
+define_pd_global(intx,     CodeCacheExpansionSize,       32*K );
+define_pd_global(uintx,    CodeCacheMinBlockLength,      1    );
+define_pd_global(uintx,    PermSize,                     12*M );
+define_pd_global(uintx,    MaxPermSize,                  64*M );
+define_pd_global(bool,     NeverActAsServerClassMachine, true );
+define_pd_global(uint64_t, MaxRAM,                       1ULL*G);
+define_pd_global(bool,     CICompileOSR,                 true );
--- a/hotspot/src/os/linux/launcher/java_md.c	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os/linux/launcher/java_md.c	Thu Sep 02 12:17:21 2010 -0700
@@ -79,6 +79,10 @@
 #    define ARCH "i386"
 #  elif defined(__sparc)
 #    define ARCH "sparc"
+#  elif defined(arm)
+#    define ARCH "arm"
+#  elif defined(PPC)
+#    define ARCH "ppc"
 #  endif
 
 #endif /* _LP64 */
--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -32,11 +32,15 @@
 #include <sys/un.h>
 #include <sys/stat.h>
 
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX   sizeof(((struct sockaddr_un *)0)->sun_path)
+#endif
+
 // The attach mechanism on Linux uses a UNIX domain socket. An attach listener
 // thread is created at startup or is created on-demand via a signal from
 // the client tool. The attach listener creates a socket and binds it to a file
 // in the filesystem. The attach listener then acts as a simple (single-
-// threaded) server - tt waits for a client to connect, reads the request,
+// threaded) server - it waits for a client to connect, reads the request,
 // executes it, and returns the response to the client via the socket
 // connection.
 //
@@ -54,7 +58,7 @@
 class LinuxAttachListener: AllStatic {
  private:
   // the path to which we bind the UNIX domain socket
-  static char _path[PATH_MAX+1];
+  static char _path[UNIX_PATH_MAX];
   static bool _has_path;
 
   // the file descriptor for the listening socket
@@ -64,8 +68,8 @@
     if (path == NULL) {
       _has_path = false;
     } else {
-      strncpy(_path, path, PATH_MAX);
-      _path[PATH_MAX] = '\0';
+      strncpy(_path, path, UNIX_PATH_MAX);
+      _path[UNIX_PATH_MAX-1] = '\0';
       _has_path = true;
     }
   }
@@ -113,7 +117,7 @@
 };
 
 // statics
-char LinuxAttachListener::_path[PATH_MAX+1];
+char LinuxAttachListener::_path[UNIX_PATH_MAX];
 bool LinuxAttachListener::_has_path;
 int LinuxAttachListener::_listener = -1;
 
@@ -163,54 +167,53 @@
 // Initialization - create a listener socket and bind it to a file
 
 int LinuxAttachListener::init() {
-  char path[PATH_MAX+1];        // socket file
-  int listener;                 // listener socket (file descriptor)
+  char path[UNIX_PATH_MAX];          // socket file
+  char initial_path[UNIX_PATH_MAX];  // socket file during setup
+  int listener;                      // listener socket (file descriptor)
 
   // register function to cleanup
   ::atexit(listener_cleanup);
 
+  int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
+                   os::get_temp_directory(), os::current_process_id());
+  if (n <= (int)UNIX_PATH_MAX) {
+    n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
+  }
+  if (n > (int)UNIX_PATH_MAX) {
+    return -1;
+  }
+
   // create the listener socket
   listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
   if (listener == -1) {
     return -1;
   }
 
-  int res = -1;
+  // bind socket
   struct sockaddr_un addr;
   addr.sun_family = AF_UNIX;
-
-  // FIXME: Prior to b39 the tool-side API expected to find the well
-  // known file in the working directory. To allow this libjvm.so work with
-  // a pre-b39 SDK we create it in the working directory if
-  // +StartAttachListener is used is used. All unit tests for this feature
-  // currently used this flag. Once b39 SDK has been promoted we can remove
-  // this code.
-  if (StartAttachListener) {
-    sprintf(path, ".java_pid%d", os::current_process_id());
-    strcpy(addr.sun_path, path);
-    ::unlink(path);
-    res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
-  }
-  if (res == -1) {
-    snprintf(path, PATH_MAX+1, "%s/.java_pid%d",
-             os::get_temp_directory(), os::current_process_id());
-    strcpy(addr.sun_path, path);
-    ::unlink(path);
-    res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
-  }
+  strcpy(addr.sun_path, initial_path);
+  ::unlink(initial_path);
+  int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
   if (res == -1) {
     RESTARTABLE(::close(listener), res);
     return -1;
   }
-  set_path(path);
 
-  // put in listen mode and set permission
-  if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) {
+  // put in listen mode, set permissions, and rename into place
+  res = ::listen(listener, 5);
+  if (res == 0) {
+      RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
+      if (res == 0) {
+          res = ::rename(initial_path, path);
+      }
+  }
+  if (res == -1) {
     RESTARTABLE(::close(listener), res);
-    ::unlink(path);
-    set_path(NULL);
+    ::unlink(initial_path);
     return -1;
   }
+  set_path(path);
   set_listener(listener);
 
   return 0;
--- a/hotspot/src/os/linux/vm/globals_linux.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -29,9 +29,10 @@
   product(bool, UseOprofile, false,                                 \
         "enable support for Oprofile profiler")                     \
                                                                     \
-  product(bool, UseLinuxPosixThreadCPUClocks, false,                \
-          "enable fast Linux Posix clocks where available")         \
-
+  product(bool, UseLinuxPosixThreadCPUClocks, true,                 \
+          "enable fast Linux Posix clocks where available")
+// NB: The default value of UseLinuxPosixThreadCPUClocks may be
+// overridden in Arguments::parse_each_vm_init_arg.
 
 //
 // Defines Linux-specific default values. The flags are available on all
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -30,6 +30,8 @@
 // put OS-includes here
 # include <sys/types.h>
 # include <sys/mman.h>
+# include <sys/stat.h>
+# include <sys/select.h>
 # include <pthread.h>
 # include <signal.h>
 # include <errno.h>
@@ -188,6 +190,10 @@
 static char cpu_arch[] = "i386";
 #elif defined(AMD64)
 static char cpu_arch[] = "amd64";
+#elif defined(ARM)
+static char cpu_arch[] = "arm";
+#elif defined(PPC)
+static char cpu_arch[] = "ppc";
 #elif defined(SPARC)
 #  ifdef _LP64
 static char cpu_arch[] = "sparcv9";
@@ -1137,8 +1143,8 @@
     long it_real;
     uintptr_t start;
     uintptr_t vsize;
-    uintptr_t rss;
-    unsigned long rsslim;
+    intptr_t rss;
+    uintptr_t rsslim;
     uintptr_t scodes;
     uintptr_t ecode;
     int i;
@@ -1168,12 +1174,12 @@
         // Skip blank chars
         do s++; while (isspace(*s));
 
-        /*                                     1   1   1   1   1   1   1   1   1   1   2   2   2   2   2   2   2   2   2 */
-        /*              3  4  5  6  7  8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8 */
-        i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld "
-                   UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT
-                   " %lu "
-                   UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT,
+#define _UFM UINTX_FORMAT
+#define _DFM INTX_FORMAT
+
+        /*                                     1   1   1   1   1   1   1   1   1   1   2   2    2    2    2    2    2    2    2 */
+        /*              3  4  5  6  7  8   9   0   1   2   3   4   5   6   7   8   9   0   1    2    3    4    5    6    7    8 */
+        i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM,
              &state,          /* 3  %c  */
              &ppid,           /* 4  %d  */
              &pgrp,           /* 5  %d  */
@@ -1193,15 +1199,18 @@
              &nice,           /* 19 %ld  */
              &junk,           /* 20 %ld  */
              &it_real,        /* 21 %ld  */
-             &start,          /* 22 UINTX_FORMAT  */
-             &vsize,          /* 23 UINTX_FORMAT  */
-             &rss,            /* 24 UINTX_FORMAT  */
-             &rsslim,         /* 25 %lu  */
-             &scodes,         /* 26 UINTX_FORMAT  */
-             &ecode,          /* 27 UINTX_FORMAT  */
-             &stack_start);   /* 28 UINTX_FORMAT  */
+             &start,          /* 22 UINTX_FORMAT */
+             &vsize,          /* 23 UINTX_FORMAT */
+             &rss,            /* 24 INTX_FORMAT  */
+             &rsslim,         /* 25 UINTX_FORMAT */
+             &scodes,         /* 26 UINTX_FORMAT */
+             &ecode,          /* 27 UINTX_FORMAT */
+             &stack_start);   /* 28 UINTX_FORMAT */
       }
 
+#undef _UFM
+#undef _DFM
+
       if (i != 28 - 2) {
          assert(false, "Bad conversion from /proc/self/stat");
          // product mode - assume we are the initial thread, good luck in the
@@ -1336,14 +1345,16 @@
 
 #if defined(IA32) || defined(AMD64)
 #define SYS_clock_getres IA32_ONLY(266)  AMD64_ONLY(229)
+#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
 #else
-#error Value of SYS_clock_getres not known on this platform
+#warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
+#define sys_clock_getres(x,y)  -1
 #endif
 
+#else
+#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
 #endif
 
-#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
-
 void os::Linux::fast_thread_clock_init() {
   if (!UseLinuxPosixThreadCPUClocks) {
     return;
@@ -1905,7 +1916,9 @@
       !_print_ascii_file("/etc/SuSE-release", st) &&
       !_print_ascii_file("/etc/turbolinux-release", st) &&
       !_print_ascii_file("/etc/gentoo-release", st) &&
-      !_print_ascii_file("/etc/debian_version", st)) {
+      !_print_ascii_file("/etc/debian_version", st) &&
+      !_print_ascii_file("/etc/ltib-release", st) &&
+      !_print_ascii_file("/etc/angstrom-version", st)) {
       st->print("Linux");
   }
   st->cr();
@@ -1971,6 +1984,11 @@
   os::loadavg(loadavg, 3);
   st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
   st->cr();
+
+  // meminfo
+  st->print("\n/proc/meminfo:\n");
+  _print_ascii_file("/proc/meminfo", st);
+  st->cr();
 }
 
 void os::print_memory_info(outputStream* st) {
@@ -2097,7 +2115,8 @@
                 CAST_FROM_FN_PTR(address, os::jvm_path),
                 dli_fname, sizeof(dli_fname), NULL);
   assert(ret != 0, "cannot locate libjvm");
-  if (realpath(dli_fname, buf) == NULL)
+  char *rp = realpath(dli_fname, buf);
+  if (rp == NULL)
     return;
 
   if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
@@ -2125,7 +2144,8 @@
         assert(strstr(p, "/libjvm") == p, "invalid library name");
         p = strstr(p, "_g") ? "_g" : "";
 
-        if (realpath(java_home_var, buf) == NULL)
+        rp = realpath(java_home_var, buf);
+        if (rp == NULL)
           return;
 
         // determine if this is a legacy image or modules image
@@ -2147,7 +2167,8 @@
           snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p);
         } else {
           // Go back to path of .so
-          if (realpath(dli_fname, buf) == NULL)
+          rp = realpath(dli_fname, buf);
+          if (rp == NULL)
             return;
         }
       }
@@ -2508,9 +2529,9 @@
 unsigned long* os::Linux::_numa_all_nodes;
 
 bool os::uncommit_memory(char* addr, size_t size) {
-  return ::mmap(addr, size, PROT_NONE,
-                MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0)
-    != MAP_FAILED;
+  uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
+                MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
+  return res  != (uintptr_t) MAP_FAILED;
 }
 
 // Linux uses a growable mapping for the stack, and if the mapping for
@@ -2718,7 +2739,8 @@
     // the processor.
 
 #ifndef ZERO
-    _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M);
+    _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
+                       ARM_ONLY(2 * M) PPC_ONLY(4 * M);
 #endif // ZERO
 
     FILE *fp = fopen("/proc/meminfo", "r");
@@ -3981,6 +4003,9 @@
   return JNI_OK;
 }
 
+// this is called at the end of vm_initialization
+void os::init_3(void) { }
+
 // Mark the polling page as unreadable
 void os::make_polling_page_unreadable(void) {
   if( !guard_memory((char*)_polling_page, Linux::page_size()) )
@@ -4061,7 +4086,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // debug support
 
-#ifndef PRODUCT
 static address same_page(address x, address y) {
   int page_bits = -os::vm_page_size();
   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
@@ -4072,26 +4096,26 @@
     return (address)(intptr_t(y) & page_bits);
 }
 
-bool os::find(address addr) {
+bool os::find(address addr, outputStream* st) {
   Dl_info dlinfo;
   memset(&dlinfo, 0, sizeof(dlinfo));
   if (dladdr(addr, &dlinfo)) {
-    tty->print(PTR_FORMAT ": ", addr);
+    st->print(PTR_FORMAT ": ", addr);
     if (dlinfo.dli_sname != NULL) {
-      tty->print("%s+%#x", dlinfo.dli_sname,
+      st->print("%s+%#x", dlinfo.dli_sname,
                  addr - (intptr_t)dlinfo.dli_saddr);
     } else if (dlinfo.dli_fname) {
-      tty->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
+      st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
     } else {
-      tty->print("<absolute address>");
+      st->print("<absolute address>");
     }
     if (dlinfo.dli_fname) {
-      tty->print(" in %s", dlinfo.dli_fname);
+      st->print(" in %s", dlinfo.dli_fname);
     }
     if (dlinfo.dli_fbase) {
-      tty->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
+      st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
     }
-    tty->cr();
+    st->cr();
 
     if (Verbose) {
       // decode some bytes around the PC
@@ -4104,15 +4128,13 @@
       if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
           && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
         end = (address) dlinfo2.dli_saddr;
-      Disassembler::decode(begin, end);
+      Disassembler::decode(begin, end, st);
     }
     return true;
   }
   return false;
 }
 
-#endif
-
 ////////////////////////////////////////////////////////////////////////////////
 // misc
 
@@ -4321,6 +4343,7 @@
   int count;
   long sys_time, user_time;
   char string[64];
+  char cdummy;
   int idummy;
   long ldummy;
   FILE *fp;
@@ -4381,11 +4404,11 @@
   // Skip blank chars
   do s++; while (isspace(*s));
 
-  count = sscanf(s,"%*c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
-                 &idummy, &idummy, &idummy, &idummy, &idummy,
+  count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
+                 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
                  &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
                  &user_time, &sys_time);
-  if ( count != 12 ) return -1;
+  if ( count != 13 ) return -1;
   if (user_sys_cpu_time) {
     return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
   } else {
@@ -4980,3 +5003,43 @@
     }
   }
 }
+
+// is_headless_jre()
+//
+// Test for the existence of libmawt in motif21 or xawt directories
+// in order to report if we are running in a headless jre
+//
+bool os::is_headless_jre() {
+    struct stat statbuf;
+    char buf[MAXPATHLEN];
+    char libmawtpath[MAXPATHLEN];
+    const char *xawtstr  = "/xawt/libmawt.so";
+    const char *motifstr = "/motif21/libmawt.so";
+    char *p;
+
+    // Get path to libjvm.so
+    os::jvm_path(buf, sizeof(buf));
+
+    // Get rid of libjvm.so
+    p = strrchr(buf, '/');
+    if (p == NULL) return false;
+    else *p = '\0';
+
+    // Get rid of client or server
+    p = strrchr(buf, '/');
+    if (p == NULL) return false;
+    else *p = '\0';
+
+    // check xawt/libmawt.so
+    strcpy(libmawtpath, buf);
+    strcat(libmawtpath, xawtstr);
+    if (::stat(libmawtpath, &statbuf) == 0) return false;
+
+    // check motif21/libmawt.so
+    strcpy(libmawtpath, buf);
+    strcat(libmawtpath, motifstr);
+    if (::stat(libmawtpath, &statbuf) == 0) return false;
+
+    return true;
+}
+
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -364,6 +364,7 @@
 // Create the door
 int SolarisAttachListener::create_door() {
   char door_path[PATH_MAX+1];
+  char initial_path[PATH_MAX+1];
   int fd, res;
 
   // register exit function
@@ -375,36 +376,46 @@
     return -1;
   }
 
+  // create initial file to attach door descriptor
   snprintf(door_path, sizeof(door_path), "%s/.java_pid%d",
            os::get_temp_directory(), os::current_process_id());
-  RESTARTABLE(::creat(door_path, S_IRUSR | S_IWUSR), fd);
-
+  snprintf(initial_path, sizeof(initial_path), "%s.tmp", door_path);
+  RESTARTABLE(::creat(initial_path, S_IRUSR | S_IWUSR), fd);
   if (fd == -1) {
-    debug_only(warning("attempt to create %s failed", door_path));
+    debug_only(warning("attempt to create %s failed", initial_path));
+    ::door_revoke(dd);
     return -1;
   }
   assert(fd >= 0, "bad file descriptor");
-  set_door_path(door_path);
   RESTARTABLE(::close(fd), res);
 
   // attach the door descriptor to the file
-  if ((res = ::fattach(dd, door_path)) == -1) {
+  if ((res = ::fattach(dd, initial_path)) == -1) {
     // if busy then detach and try again
     if (errno == EBUSY) {
-      ::fdetach(door_path);
-      res = ::fattach(dd, door_path);
+      ::fdetach(initial_path);
+      res = ::fattach(dd, initial_path);
     }
     if (res == -1) {
       ::door_revoke(dd);
       dd = -1;
     }
   }
+
+  // rename file so that clients can attach
+  if (dd >= 0) {
+    if (::rename(initial_path, door_path) == -1) {
+        RESTARTABLE(::close(dd), res);
+        ::fdetach(initial_path);
+        dd = -1;
+    }
+  }
   if (dd >= 0) {
     set_door_descriptor(dd);
+    set_door_path(door_path);
   } else {
-    // unable to create door or attach it to the file
-    ::unlink(door_path);
-    set_door_path(NULL);
+    // unable to create door, attach it to file, or rename file into place
+    ::unlink(initial_path);
     return -1;
   }
 
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1839,8 +1839,8 @@
 
   // Quietly truncate on buffer overflow.  Should be an error.
   if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
-      *buffer = '\0';
-      return;
+    *buffer = '\0';
+    return;
   }
 
   if (pnamelen == 0) {
@@ -2051,7 +2051,8 @@
     {EM_SPARC32PLUS, EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
     {EM_SPARCV9,     EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
     {EM_PPC,         EM_PPC,     ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
-    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}
+    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
+    {EM_ARM,         EM_ARM,     ELFCLASS32, ELFDATA2LSB, (char*)"ARM 32"}
   };
 
   #if  (defined IA32)
@@ -2068,9 +2069,11 @@
     static  Elf32_Half running_arch_code=EM_PPC64;
   #elif  (defined __powerpc__)
     static  Elf32_Half running_arch_code=EM_PPC;
+  #elif (defined ARM)
+    static  Elf32_Half running_arch_code=EM_ARM;
   #else
     #error Method os::dll_load requires that one of following is defined:\
-         IA32, AMD64, IA64, __sparc, __powerpc__
+         IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM
   #endif
 
   // Identify compatability class for VM's architecture and library's architecture
@@ -3149,7 +3152,8 @@
   // ISM is only recommended on old Solaris where there is no MPSS support.
   // Simply choose a conservative value as default.
   *page_size = LargePageSizeInBytes ? LargePageSizeInBytes :
-               SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M);
+               SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M)
+               ARM_ONLY(2 * M);
 
   // ISM is available on all supported Solaris versions
   return true;
@@ -5007,6 +5011,9 @@
   return JNI_OK;
 }
 
+void os::init_3(void) {
+  return;
+}
 
 // Mark the polling page as unreadable
 void os::make_polling_page_unreadable(void) {
@@ -5412,7 +5419,6 @@
 }
 
 //---------------------------------------------------------------------------------
-#ifndef PRODUCT
 
 static address same_page(address x, address y) {
   intptr_t page_bits = -os::vm_page_size();
@@ -5424,28 +5430,28 @@
     return (address)(intptr_t(y) & page_bits);
 }
 
-bool os::find(address addr) {
+bool os::find(address addr, outputStream* st) {
   Dl_info dlinfo;
   memset(&dlinfo, 0, sizeof(dlinfo));
   if (dladdr(addr, &dlinfo)) {
 #ifdef _LP64
-    tty->print("0x%016lx: ", addr);
+    st->print("0x%016lx: ", addr);
 #else
-    tty->print("0x%08x: ", addr);
+    st->print("0x%08x: ", addr);
 #endif
     if (dlinfo.dli_sname != NULL)
-      tty->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
+      st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
     else if (dlinfo.dli_fname)
-      tty->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase);
+      st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase);
     else
-      tty->print("<absolute address>");
-    if (dlinfo.dli_fname)  tty->print(" in %s", dlinfo.dli_fname);
+      st->print("<absolute address>");
+    if (dlinfo.dli_fname)  st->print(" in %s", dlinfo.dli_fname);
 #ifdef _LP64
-    if (dlinfo.dli_fbase)  tty->print(" at 0x%016lx", dlinfo.dli_fbase);
+    if (dlinfo.dli_fbase)  st->print(" at 0x%016lx", dlinfo.dli_fbase);
 #else
-    if (dlinfo.dli_fbase)  tty->print(" at 0x%08x", dlinfo.dli_fbase);
+    if (dlinfo.dli_fbase)  st->print(" at 0x%08x", dlinfo.dli_fbase);
 #endif
-    tty->cr();
+    st->cr();
 
     if (Verbose) {
       // decode some bytes around the PC
@@ -5458,16 +5464,13 @@
       if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
           && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
         end = (address) dlinfo2.dli_saddr;
-      Disassembler::decode(begin, end);
+      Disassembler::decode(begin, end, st);
     }
     return true;
   }
   return false;
 }
 
-#endif
-
-
 // Following function has been added to support HotSparc's libjvm.so running
 // under Solaris production JDK 1.2.2 / 1.3.0.  These came from
 // src/solaris/hpi/native_threads in the EVM codebase.
@@ -5910,7 +5913,6 @@
   if (jt->handle_special_suspend_equivalent_condition()) {
     jt->java_suspend_self();
   }
-
   OrderAccess::fence();
 }
 
@@ -5997,3 +5999,44 @@
     }
   }
 }
+
+// is_headless_jre()
+//
+// Test for the existence of libmawt in motif21 or xawt directories
+// in order to report if we are running in a headless jre
+//
+bool os::is_headless_jre() {
+    struct stat statbuf;
+    char buf[MAXPATHLEN];
+    char libmawtpath[MAXPATHLEN];
+    const char *xawtstr  = "/xawt/libmawt.so";
+    const char *motifstr = "/motif21/libmawt.so";
+    char *p;
+
+    // Get path to libjvm.so
+    os::jvm_path(buf, sizeof(buf));
+
+    // Get rid of libjvm.so
+    p = strrchr(buf, '/');
+    if (p == NULL) return false;
+    else *p = '\0';
+
+    // Get rid of client or server
+    p = strrchr(buf, '/');
+    if (p == NULL) return false;
+    else *p = '\0';
+
+    // check xawt/libmawt.so
+    strcpy(libmawtpath, buf);
+    strcat(libmawtpath, xawtstr);
+    if (::stat(libmawtpath, &statbuf) == 0) return false;
+
+    // check motif21/libmawt.so
+    strcpy(libmawtpath, buf);
+    strcat(libmawtpath, motifstr);
+    if (::stat(libmawtpath, &statbuf) == 0) return false;
+
+    return true;
+}
+
+
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -3444,6 +3444,9 @@
   return JNI_OK;
 }
 
+void os::init_3(void) {
+  return;
+}
 
 // Mark the polling page as unreadable
 void os::make_polling_page_unreadable(void) {
@@ -4105,12 +4108,10 @@
 }
 
 
-#ifndef PRODUCT
-bool os::find(address addr) {
+bool os::find(address addr, outputStream* st) {
   // Nothing yet
   return false;
 }
-#endif
 
 LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {
   DWORD exception_code = e->ExceptionRecord->ExceptionCode;
@@ -4164,3 +4165,8 @@
     }
     return 0;
 }
+
+
+// We don't build a headless jre for Windows
+bool os::is_headless_jre() { return false; }
+
--- a/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -105,3 +105,6 @@
   // nothing else to try
   return false;
 }
+
+void JavaThread::cache_global_variables() { }
+
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -718,6 +718,11 @@
 
   ucontext_t *uc = (ucontext_t*)context;
   st->print_cr("Registers:");
+
+  // this is horrendously verbose but the layout of the registers in the
+  // context does not match how we defined our abstract Register set, so
+  // we can't just iterate through the gregs area
+
 #ifdef AMD64
   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
   st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
@@ -745,6 +750,63 @@
   st->print(", ERR=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ERR]);
   st->cr();
   st->print("  TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]);
+
+  st->cr();
+  st->cr();
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+  st->print_cr("RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
+  st->cr();
+  st->print_cr("RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
+  st->cr();
+  st->print_cr("RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
+  st->cr();
+  st->print_cr("RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
+  st->cr();
+  st->print_cr("RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
+  st->cr();
+  st->print_cr("RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RBP]);
+  st->cr();
+  st->print_cr("RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
+  st->cr();
+  st->print_cr("RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
+  st->cr();
+  st->print_cr("R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R8]);
+  st->cr();
+  st->print_cr("R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R9]);
+  st->cr();
+  st->print_cr("R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R10]);
+  st->cr();
+  st->print_cr("R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R11]);
+  st->cr();
+  st->print_cr("R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R12]);
+  st->cr();
+  st->print_cr("R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R13]);
+  st->cr();
+  st->print_cr("R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R14]);
+  st->cr();
+  st->print_cr("R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R15]);
+
 #else
   st->print(  "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
   st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
@@ -759,6 +821,39 @@
   st->print(  "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]);
   st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2);
   st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
+
+  st->cr();
+  st->cr();
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+  st->print_cr("EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_EAX]);
+  st->cr();
+  st->print_cr("EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_EBX]);
+  st->cr();
+  st->print_cr("ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ECX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_ECX]);
+  st->cr();
+  st->print_cr("EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_EDX]);
+  st->cr();
+  st->print_cr("ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESP]);
+  print_location(st, uc->uc_mcontext.gregs[REG_ESP]);
+  st->cr();
+  st->print_cr("EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBP]);
+  print_location(st, uc->uc_mcontext.gregs[REG_EBP]);
+  st->cr();
+  st->print_cr("ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESI]);
+  print_location(st, uc->uc_mcontext.gregs[REG_ESI]);
+  st->cr();
+  st->print_cr("EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]);
+  print_location(st, uc->uc_mcontext.gregs[REG_EDI]);
+
 #endif // AMD64
   st->cr();
   st->cr();
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
   // nothing else to try
   return false;
 }
+
+void JavaThread::cache_global_variables() { }
+
--- a/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -24,3 +24,5 @@
  */
 
 // This file is intentionally empty
+
+void JavaThread::cache_global_variables() { }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -587,6 +587,61 @@
   st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT,
             uc->uc_mcontext.gregs[REG_PC],
             uc->uc_mcontext.gregs[REG_nPC]);
+
+  st->cr();
+  st->cr();
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+  st->print_cr("O0=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O0]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O0]);
+  st->cr();
+  st->print_cr("O1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O1]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O1]);
+  st->cr();
+  st->print_cr("O2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O2]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O2]);
+  st->cr();
+  st->print_cr("O3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O3]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O3]);
+  st->cr();
+  st->print_cr("O4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O4]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O4]);
+  st->cr();
+  st->print_cr("O5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O5]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O5]);
+  st->cr();
+  st->print_cr("O6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O6]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O6]);
+  st->cr();
+  st->print_cr("O7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O7]);
+  print_location(st, uc->uc_mcontext.gregs[REG_O7]);
+  st->cr();
+
+  st->print_cr("G1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G1]);
+  print_location(st, uc->uc_mcontext.gregs[REG_G1]);
+  st->cr();
+  st->print_cr("G2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G2]);
+  print_location(st, uc->uc_mcontext.gregs[REG_G2]);
+  st->cr();
+  st->print_cr("G3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G3]);
+  print_location(st, uc->uc_mcontext.gregs[REG_G3]);
+  st->cr();
+  st->print_cr("G4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G4]);
+  print_location(st, uc->uc_mcontext.gregs[REG_G4]);
+  st->cr();
+  st->print_cr("G5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G5]);
+  print_location(st, uc->uc_mcontext.gregs[REG_G5]);
+  st->cr();
+  st->print_cr("G6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G6]);
+  print_location(st, uc->uc_mcontext.gregs[REG_G6]);
+  st->cr();
+  st->print_cr("G7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G7]);
+  print_location(st, uc->uc_mcontext.gregs[REG_G7]);
+
   st->cr();
   st->cr();
 
--- a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -140,3 +140,6 @@
   *fr_addr = ret_frame;
   return true;
 }
+
+void JavaThread::cache_global_variables() { }
+
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -719,6 +719,11 @@
 
   ucontext_t *uc = (ucontext_t*)context;
   st->print_cr("Registers:");
+
+  // this is horrendously verbose but the layout of the registers in the
+  // context does not match how we defined our abstract Register set, so
+  // we can't just iterate through the gregs area
+
 #ifdef AMD64
   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
   st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
@@ -742,6 +747,63 @@
   st->cr();
   st->print(  "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]);
   st->print(", RFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RFL]);
+
+  st->cr();
+  st->cr();
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+  st->print_cr("RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
+  st->cr();
+  st->print_cr("RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
+  st->cr();
+  st->print_cr("RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
+  st->cr();
+  st->print_cr("RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
+  st->cr();
+  st->print_cr("RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
+  st->cr();
+  st->print_cr("RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
+  st->cr();
+  st->print_cr("RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
+  st->cr();
+  st->print_cr("RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
+  print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
+  st->cr();
+  st->print_cr("R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R8]);
+  st->cr();
+  st->print_cr("R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R9]);
+  st->cr();
+  st->print_cr("R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R10]);
+  st->cr();
+  st->print_cr("R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R11]);
+  st->cr();
+  st->print_cr("R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R12]);
+  st->cr();
+  st->print_cr("R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R13]);
+  st->cr();
+  st->print_cr("R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R14]);
+  st->cr();
+  st->print_cr("R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
+  print_location(st, uc->uc_mcontext.gregs[REG_R15]);
+
 #else
   st->print(  "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]);
   st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]);
@@ -755,6 +817,39 @@
   st->cr();
   st->print(  "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EIP]);
   st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EFL]);
+
+  st->cr();
+  st->cr();
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+  st->print_cr("EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]);
+  print_location(st, uc->uc_mcontext.gregs[EAX]);
+  st->cr();
+  st->print_cr("EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]);
+  print_location(st, uc->uc_mcontext.gregs[EBX]);
+  st->cr();
+  st->print_cr("ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ECX]);
+  print_location(st, uc->uc_mcontext.gregs[ECX]);
+  st->cr();
+  st->print_cr("EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDX]);
+  print_location(st, uc->uc_mcontext.gregs[EDX]);
+  st->cr();
+  st->print_cr("ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[UESP]);
+  print_location(st, uc->uc_mcontext.gregs[UESP]);
+  st->cr();
+  st->print_cr("EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBP]);
+  print_location(st, uc->uc_mcontext.gregs[EBP]);
+  st->cr();
+  st->print_cr("ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ESI]);
+  print_location(st, uc->uc_mcontext.gregs[ESI]);
+  st->cr();
+  st->print_cr("EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDI]);
+  print_location(st, uc->uc_mcontext.gregs[EDI]);
+
 #endif // AMD64
   st->cr();
   st->cr();
@@ -773,6 +868,7 @@
   print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
 }
 
+
 #ifdef AMD64
 void os::Solaris::init_thread_fpu_state(void) {
   // Nothing to do
--- a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -82,3 +82,6 @@
   return true;
 
 }
+
+void JavaThread::cache_global_variables() { }
+
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -377,18 +377,84 @@
 
   st->print_cr("Registers:");
 #ifdef AMD64
-  st->print(  "EAX=" INTPTR_FORMAT, uc->Rax);
-  st->print(", EBX=" INTPTR_FORMAT, uc->Rbx);
-  st->print(", ECX=" INTPTR_FORMAT, uc->Rcx);
-  st->print(", EDX=" INTPTR_FORMAT, uc->Rdx);
+  st->print(  "RAX=" INTPTR_FORMAT, uc->Rax);
+  st->print(", RBX=" INTPTR_FORMAT, uc->Rbx);
+  st->print(", RCX=" INTPTR_FORMAT, uc->Rcx);
+  st->print(", RDX=" INTPTR_FORMAT, uc->Rdx);
+  st->cr();
+  st->print(  "RSP=" INTPTR_FORMAT, uc->Rsp);
+  st->print(", RBP=" INTPTR_FORMAT, uc->Rbp);
+  st->print(", RSI=" INTPTR_FORMAT, uc->Rsi);
+  st->print(", RDI=" INTPTR_FORMAT, uc->Rdi);
+  st->cr();
+  st->print(  "R8=" INTPTR_FORMAT,  uc->R8);
+  st->print(", R9=" INTPTR_FORMAT,  uc->R9);
+  st->print(", R10=" INTPTR_FORMAT, uc->R10);
+  st->print(", R11=" INTPTR_FORMAT, uc->R11);
+  st->cr();
+  st->print(  "R12=" INTPTR_FORMAT, uc->R12);
+  st->print(", R13=" INTPTR_FORMAT, uc->R13);
+  st->print(", R14=" INTPTR_FORMAT, uc->R14);
+  st->print(", R15=" INTPTR_FORMAT, uc->R15);
+  st->cr();
+  st->print(  "RIP=" INTPTR_FORMAT, uc->Rip);
+  st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
+
+  st->cr();
+  st->cr();
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+  st->print_cr("RAX=" INTPTR_FORMAT, uc->Rax);
+  print_location(st, uc->Rax);
+  st->cr();
+  st->print_cr("RBX=" INTPTR_FORMAT, uc->Rbx);
+  print_location(st, uc->Rbx);
   st->cr();
-  st->print(  "ESP=" INTPTR_FORMAT, uc->Rsp);
-  st->print(", EBP=" INTPTR_FORMAT, uc->Rbp);
-  st->print(", ESI=" INTPTR_FORMAT, uc->Rsi);
-  st->print(", EDI=" INTPTR_FORMAT, uc->Rdi);
+  st->print_cr("RCX=" INTPTR_FORMAT, uc->Rcx);
+  print_location(st, uc->Rcx);
+  st->cr();
+  st->print_cr("RDX=" INTPTR_FORMAT, uc->Rdx);
+  print_location(st, uc->Rdx);
+  st->cr();
+  st->print_cr("RSP=" INTPTR_FORMAT, uc->Rsp);
+  print_location(st, uc->Rsp);
+  st->cr();
+  st->print_cr("RBP=" INTPTR_FORMAT, uc->Rbp);
+  print_location(st, uc->Rbp);
+  st->cr();
+  st->print_cr("RSI=" INTPTR_FORMAT, uc->Rsi);
+  print_location(st, uc->Rsi);
+  st->cr();
+  st->print_cr("RDI=" INTPTR_FORMAT, uc->Rdi);
+  print_location(st, uc->Rdi);
+  st->cr();
+  st->print_cr("R8 =" INTPTR_FORMAT, uc->R8);
+  print_location(st, uc->R8);
   st->cr();
-  st->print(  "EIP=" INTPTR_FORMAT, uc->Rip);
-  st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
+  st->print_cr("R9 =" INTPTR_FORMAT, uc->R9);
+  print_location(st, uc->R9);
+  st->cr();
+  st->print_cr("R10=" INTPTR_FORMAT, uc->R10);
+  print_location(st, uc->R10);
+  st->cr();
+  st->print_cr("R11=" INTPTR_FORMAT, uc->R11);
+  print_location(st, uc->R11);
+  st->cr();
+  st->print_cr("R12=" INTPTR_FORMAT, uc->R12);
+  print_location(st, uc->R12);
+  st->cr();
+  st->print_cr("R13=" INTPTR_FORMAT, uc->R13);
+  print_location(st, uc->R13);
+  st->cr();
+  st->print_cr("R14=" INTPTR_FORMAT, uc->R14);
+  print_location(st, uc->R14);
+  st->cr();
+  st->print_cr("R15=" INTPTR_FORMAT, uc->R15);
+  print_location(st, uc->R15);
 #else
   st->print(  "EAX=" INTPTR_FORMAT, uc->Eax);
   st->print(", EBX=" INTPTR_FORMAT, uc->Ebx);
@@ -402,6 +468,38 @@
   st->cr();
   st->print(  "EIP=" INTPTR_FORMAT, uc->Eip);
   st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
+
+  st->cr();
+  st->cr();
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+  st->print_cr("EAX=" INTPTR_FORMAT, uc->Eax);
+  print_location(st, uc->Eax);
+  st->cr();
+  st->print_cr("EBX=" INTPTR_FORMAT, uc->Ebx);
+  print_location(st, uc->Ebx);
+  st->cr();
+  st->print_cr("ECX=" INTPTR_FORMAT, uc->Ecx);
+  print_location(st, uc->Ecx);
+  st->cr();
+  st->print_cr("EDX=" INTPTR_FORMAT, uc->Edx);
+  print_location(st, uc->Edx);
+  st->cr();
+  st->print_cr("ESP=" INTPTR_FORMAT, uc->Esp);
+  print_location(st, uc->Esp);
+  st->cr();
+  st->print_cr("EBP=" INTPTR_FORMAT, uc->Ebp);
+  print_location(st, uc->Ebp);
+  st->cr();
+  st->print_cr("ESI=" INTPTR_FORMAT, uc->Esi);
+  print_location(st, uc->Esi);
+  st->cr();
+  st->print_cr("EDI=" INTPTR_FORMAT, uc->Edi);
+  print_location(st, uc->Edi);
 #endif // AMD64
   st->cr();
   st->cr();
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -84,3 +84,6 @@
   // nothing else to try
   return false;
 }
+
+void JavaThread::cache_global_variables() { }
+
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -128,7 +128,11 @@
   delete _overflow_arena;
 
 #ifdef ASSERT
+  // Save allocation type to execute assert in ~ResourceObj()
+  // which is called after this destructor.
+  ResourceObj::allocation_type at = _default_oop_recorder.get_allocation_type();
   Copy::fill_to_bytes(this, sizeof(*this), badResourceValue);
+  ResourceObj::set_allocation_type((address)(&_default_oop_recorder), at);
 #endif
 }
 
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -102,7 +102,7 @@
     _locs_point    = NULL;
     _locs_own      = false;
     _frozen        = false;
-    debug_only(_index = -1);
+    debug_only(_index = (char)-1);
     debug_only(_outer = (CodeBuffer*)badAddress);
   }
 
@@ -278,7 +278,7 @@
   // special case during expansion which is handled internally.  This
   // is done to guarantee proper cleanup of resources.
   void* operator new(size_t size) { return ResourceObj::operator new(size); }
-  void  operator delete(void* p)  {        ResourceObj::operator delete(p); }
+  void  operator delete(void* p)  { ShouldNotCallThis(); }
 
  public:
   typedef int csize_t;  // code size type; would be size_t except for history
--- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -448,6 +448,10 @@
     _obj(obj), _info(info), _stub(stub) {
   }
 
+  void set_obj(LIR_Opr obj) {
+    _obj = obj;
+  }
+
   virtual void emit_code(LIR_Assembler* e);
   virtual CodeEmitInfo* info() const             { return _info; }
   virtual bool is_exception_throw_stub() const   { return true; }
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -220,11 +220,13 @@
   code_offsets->set_value(CodeOffsets::Deopt, assembler->emit_deopt_handler());
   CHECK_BAILOUT();
 
-  // Generate code for MethodHandle deopt handler.  We can use the
-  // same code as for the normal deopt handler, we just need a
-  // different entry point address.
-  code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler());
-  CHECK_BAILOUT();
+  // Emit the MethodHandle deopt handler code (if required).
+  if (has_method_handle_invokes()) {
+    // We can use the same code as for the normal deopt handler, we
+    // just need a different entry point address.
+    code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler());
+    CHECK_BAILOUT();
+  }
 
   // Emit the handler to remove the activation from the stack and
   // dispatch to the caller.
@@ -446,6 +448,7 @@
 , _has_exception_handlers(false)
 , _has_fpu_code(true)   // pessimistic assumption
 , _has_unsafe_access(false)
+, _has_method_handle_invokes(false)
 , _bailout_msg(NULL)
 , _exception_info_list(NULL)
 , _allocator(NULL)
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -69,6 +69,7 @@
   bool               _has_exception_handlers;
   bool               _has_fpu_code;
   bool               _has_unsafe_access;
+  bool               _has_method_handle_invokes;  // True if this method has MethodHandle invokes.
   const char*        _bailout_msg;
   ExceptionInfoList* _exception_info_list;
   ExceptionHandlerTable _exception_handler_table;
@@ -147,6 +148,10 @@
   // Statistics gathering
   void notice_inlined_method(ciMethod* method);
 
+  // JSR 292
+  bool     has_method_handle_invokes() const { return _has_method_handle_invokes;     }
+  void set_has_method_handle_invokes(bool z) {        _has_method_handle_invokes = z; }
+
   DebugInformationRecorder* debug_info_recorder() const; // = _env->debug_info();
   Dependencies* dependency_recorder() const; // = _env->dependencies()
   ImplicitExceptionTable* implicit_exception_table()     { return &_implicit_exception_table; }
@@ -168,10 +173,19 @@
   const char* bailout_msg() const                { return _bailout_msg; }
 
   static int desired_max_code_buffer_size() {
+#ifndef PPC
     return (int) NMethodSizeLimit;  // default 256K or 512K
+#else
+    // conditional branches on PPC are restricted to 16 bit signed
+    return MAX2((unsigned int)NMethodSizeLimit,32*K);
+#endif
   }
   static int desired_max_constant_size() {
+#ifndef PPC
     return (int) NMethodSizeLimit / 10;  // about 25K
+#else
+    return (MAX2((unsigned int)NMethodSizeLimit, 32*K)) / 10;
+#endif
   }
 
   static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
--- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -90,7 +90,7 @@
 
   if (outgoing) {
     // update the space reserved for arguments.
-    update_reserved_argument_area_size(out_preserve);
+    update_reserved_argument_area_size(out_preserve * BytesPerWord);
   }
   return new CallingConvention(args, out_preserve);
 }
@@ -138,7 +138,7 @@
   }
   assert(args->length() == signature->length(), "size mismatch");
   out_preserve += SharedRuntime::out_preserve_stack_slots();
-  update_reserved_argument_area_size(out_preserve);
+  update_reserved_argument_area_size(out_preserve * BytesPerWord);
   return new CallingConvention(args, out_preserve);
 }
 
--- a/hotspot/src/share/vm/c1/c1_FrameMap.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -154,7 +154,6 @@
   static LIR_Opr method_handle_invoke_SP_save_opr();
 
   static BasicTypeArray*     signature_type_array_for(const ciMethod* method);
-  static BasicTypeArray*     signature_type_array_for(const char * signature);
 
   // for outgoing calls, these also update the reserved area to
   // include space for arguments and any ABI area.
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -50,8 +50,7 @@
 
 #endif // X86
 
-
-#ifdef SPARC
+#if defined(SPARC) || defined(PPC)
 
 FloatRegister LIR_OprDesc::as_float_reg() const {
   return FrameMap::nr2floatreg(fpu_regnr());
@@ -63,6 +62,19 @@
 
 #endif
 
+#ifdef ARM
+
+FloatRegister LIR_OprDesc::as_float_reg() const {
+  return as_FloatRegister(fpu_regnr());
+}
+
+FloatRegister LIR_OprDesc::as_double_reg() const {
+  return as_FloatRegister(fpu_regnrLo());
+}
+
+#endif
+
+
 LIR_Opr LIR_OprFact::illegalOpr = LIR_OprFact::illegal();
 
 LIR_Opr LIR_OprFact::value_type(ValueType* type) {
@@ -119,10 +131,14 @@
 
 #ifndef PRODUCT
 void LIR_Address::verify() const {
-#ifdef SPARC
-  assert(scale() == times_1, "Scaled addressing mode not available on SPARC and should not be used");
+#if defined(SPARC) || defined(PPC)
+  assert(scale() == times_1, "Scaled addressing mode not available on SPARC/PPC and should not be used");
   assert(disp() == 0 || index()->is_illegal(), "can't have both");
 #endif
+#ifdef ARM
+  assert(disp() == 0 || index()->is_illegal(), "can't have both");
+  assert(-4096 < disp() && disp() < 4096, "architecture constraint");
+#endif
 #ifdef _LP64
   assert(base()->is_cpu_register(), "wrong base operand");
   assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand");
@@ -173,13 +189,22 @@
   if (!is_pointer() && !is_illegal()) {
     switch (as_BasicType(type_field())) {
     case T_LONG:
-      assert((kind_field() == cpu_register || kind_field() == stack_value) && size_field() == double_size, "must match");
+      assert((kind_field() == cpu_register || kind_field() == stack_value) &&
+             size_field() == double_size, "must match");
       break;
     case T_FLOAT:
-      assert((kind_field() == fpu_register || kind_field() == stack_value) && size_field() == single_size, "must match");
+      // FP return values can be also in CPU registers on ARM and PPC (softfp ABI)
+      assert((kind_field() == fpu_register || kind_field() == stack_value
+             ARM_ONLY(|| kind_field() == cpu_register)
+             PPC_ONLY(|| kind_field() == cpu_register) ) &&
+             size_field() == single_size, "must match");
       break;
     case T_DOUBLE:
-      assert((kind_field() == fpu_register || kind_field() == stack_value) && size_field() == double_size, "must match");
+      // FP return values can be also in CPU registers on ARM and PPC (softfp ABI)
+      assert((kind_field() == fpu_register || kind_field() == stack_value
+             ARM_ONLY(|| kind_field() == cpu_register)
+             PPC_ONLY(|| kind_field() == cpu_register) ) &&
+             size_field() == double_size, "must match");
       break;
     case T_BOOLEAN:
     case T_CHAR:
@@ -188,7 +213,8 @@
     case T_INT:
     case T_OBJECT:
     case T_ARRAY:
-      assert((kind_field() == cpu_register || kind_field() == stack_value) && size_field() == single_size, "must match");
+      assert((kind_field() == cpu_register || kind_field() == stack_value) &&
+             size_field() == single_size, "must match");
       break;
 
     case T_ILLEGAL:
@@ -503,6 +529,10 @@
       assert(opConvert->_info == NULL, "must be");
       if (opConvert->_opr->is_valid())       do_input(opConvert->_opr);
       if (opConvert->_result->is_valid())    do_output(opConvert->_result);
+#ifdef PPC
+      if (opConvert->_tmp1->is_valid())      do_temp(opConvert->_tmp1);
+      if (opConvert->_tmp2->is_valid())      do_temp(opConvert->_tmp2);
+#endif
       do_stub(opConvert->_stub);
 
       break;
@@ -530,7 +560,9 @@
       LIR_OpAllocObj* opAllocObj = (LIR_OpAllocObj*)op;
 
       if (opAllocObj->_info)                     do_info(opAllocObj->_info);
-      if (opAllocObj->_opr->is_valid())          do_input(opAllocObj->_opr);
+      if (opAllocObj->_opr->is_valid()) {        do_input(opAllocObj->_opr);
+                                                 do_temp(opAllocObj->_opr);
+                                        }
       if (opAllocObj->_tmp1->is_valid())         do_temp(opAllocObj->_tmp1);
       if (opAllocObj->_tmp2->is_valid())         do_temp(opAllocObj->_tmp2);
       if (opAllocObj->_tmp3->is_valid())         do_temp(opAllocObj->_tmp3);
@@ -826,10 +858,16 @@
       assert(op->as_OpCompareAndSwap() != NULL, "must be");
       LIR_OpCompareAndSwap* opCompareAndSwap = (LIR_OpCompareAndSwap*)op;
 
+      assert(opCompareAndSwap->_addr->is_valid(),      "used");
+      assert(opCompareAndSwap->_cmp_value->is_valid(), "used");
+      assert(opCompareAndSwap->_new_value->is_valid(), "used");
       if (opCompareAndSwap->_info)                    do_info(opCompareAndSwap->_info);
-      if (opCompareAndSwap->_addr->is_valid())        do_input(opCompareAndSwap->_addr);
-      if (opCompareAndSwap->_cmp_value->is_valid())   do_input(opCompareAndSwap->_cmp_value);
-      if (opCompareAndSwap->_new_value->is_valid())   do_input(opCompareAndSwap->_new_value);
+                                                      do_input(opCompareAndSwap->_addr);
+                                                      do_temp(opCompareAndSwap->_addr);
+                                                      do_input(opCompareAndSwap->_cmp_value);
+                                                      do_temp(opCompareAndSwap->_cmp_value);
+                                                      do_input(opCompareAndSwap->_new_value);
+                                                      do_temp(opCompareAndSwap->_new_value);
       if (opCompareAndSwap->_tmp1->is_valid())        do_temp(opCompareAndSwap->_tmp1);
       if (opCompareAndSwap->_tmp2->is_valid())        do_temp(opCompareAndSwap->_tmp2);
       if (opCompareAndSwap->_result->is_valid())      do_output(opCompareAndSwap->_result);
@@ -1303,13 +1341,13 @@
                     info));
 }
 
-void LIR_List::unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, CodeStub* stub) {
+void LIR_List::unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub) {
   append(new LIR_OpLock(
                     lir_unlock,
                     hdr,
                     obj,
                     lock,
-                    LIR_OprFact::illegalOpr,
+                    scratch,
                     stub,
                     NULL));
 }
@@ -1342,22 +1380,19 @@
 }
 
 
-void LIR_List::cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2) {
-  // Compare and swap produces condition code "zero" if contents_of(addr) == cmp_value,
-  // implying successful swap of new_value into addr
-  append(new LIR_OpCompareAndSwap(lir_cas_long, addr, cmp_value, new_value, t1, t2));
+void LIR_List::cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
+                        LIR_Opr t1, LIR_Opr t2, LIR_Opr result) {
+  append(new LIR_OpCompareAndSwap(lir_cas_long, addr, cmp_value, new_value, t1, t2, result));
 }
 
-void LIR_List::cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2) {
-  // Compare and swap produces condition code "zero" if contents_of(addr) == cmp_value,
-  // implying successful swap of new_value into addr
-  append(new LIR_OpCompareAndSwap(lir_cas_obj, addr, cmp_value, new_value, t1, t2));
+void LIR_List::cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
+                       LIR_Opr t1, LIR_Opr t2, LIR_Opr result) {
+  append(new LIR_OpCompareAndSwap(lir_cas_obj, addr, cmp_value, new_value, t1, t2, result));
 }
 
-void LIR_List::cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2) {
-  // Compare and swap produces condition code "zero" if contents_of(addr) == cmp_value,
-  // implying successful swap of new_value into addr
-  append(new LIR_OpCompareAndSwap(lir_cas_int, addr, cmp_value, new_value, t1, t2));
+void LIR_List::cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
+                       LIR_Opr t1, LIR_Opr t2, LIR_Opr result) {
+  append(new LIR_OpCompareAndSwap(lir_cas_int, addr, cmp_value, new_value, t1, t2, result));
 }
 
 
@@ -1400,6 +1435,11 @@
     out->print("fpu%d", fpu_regnr());
   } else if (is_double_fpu()) {
     out->print("fpu%d", fpu_regnrLo());
+#elif defined(ARM)
+  } else if (is_single_fpu()) {
+    out->print("s%d", fpu_regnr());
+  } else if (is_double_fpu()) {
+    out->print("d%d", fpu_regnrLo() >> 1);
 #else
   } else if (is_single_fpu()) {
     out->print(as_float_reg()->name());
@@ -1756,6 +1796,12 @@
   print_bytecode(out, bytecode());
   in_opr()->print(out);                  out->print(" ");
   result_opr()->print(out);              out->print(" ");
+#ifdef PPC
+  if(tmp1()->is_valid()) {
+    tmp1()->print(out); out->print(" ");
+    tmp2()->print(out); out->print(" ");
+  }
+#endif
 }
 
 void LIR_OpConvert::print_bytecode(outputStream* out, Bytecodes::Code code) {
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -432,8 +432,7 @@
   // for compatibility with RInfo
   int fpu () const                                  { return lo_reg_half(); }
 #endif // X86
-
-#ifdef SPARC
+#if defined(SPARC) || defined(ARM) || defined(PPC)
   FloatRegister as_float_reg   () const;
   FloatRegister as_double_reg  () const;
 #endif
@@ -519,14 +518,14 @@
      , _type(type)
      , _disp(0) { verify(); }
 
-#ifdef X86
+#if defined(X86) || defined(ARM)
   LIR_Address(LIR_Opr base, LIR_Opr index, Scale scale, intx disp, BasicType type):
        _base(base)
      , _index(index)
      , _scale(scale)
      , _type(type)
      , _disp(disp) { verify(); }
-#endif // X86
+#endif // X86 || ARM
 
   LIR_Opr base()  const                          { return _base;  }
   LIR_Opr index() const                          { return _index; }
@@ -566,7 +565,11 @@
                                                                              LIR_OprDesc::float_type           |
                                                                              LIR_OprDesc::fpu_register         |
                                                                              LIR_OprDesc::single_size); }
-
+#if defined(ARM)
+  static LIR_Opr double_fpu(int reg1, int reg2)    { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size); }
+  static LIR_Opr single_softfp(int reg)            { return (LIR_Opr)((reg  << LIR_OprDesc::reg1_shift) |                                     LIR_OprDesc::float_type  | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); }
+  static LIR_Opr double_softfp(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::cpu_register | LIR_OprDesc::double_size); }
+#endif
 #ifdef SPARC
   static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) |
                                                                              (reg2 << LIR_OprDesc::reg2_shift) |
@@ -593,7 +596,22 @@
                                                                              LIR_OprDesc::double_size          |
                                                                              LIR_OprDesc::is_xmm_mask); }
 #endif // X86
-
+#ifdef PPC
+  static LIR_Opr double_fpu(int reg)            { return (LIR_Opr)(intptr_t)((reg  << LIR_OprDesc::reg1_shift) |
+                                                                             (reg  << LIR_OprDesc::reg2_shift) |
+                                                                             LIR_OprDesc::double_type          |
+                                                                             LIR_OprDesc::fpu_register         |
+                                                                             LIR_OprDesc::double_size); }
+  static LIR_Opr single_softfp(int reg)            { return (LIR_Opr)((reg  << LIR_OprDesc::reg1_shift)        |
+                                                                             LIR_OprDesc::float_type           |
+                                                                             LIR_OprDesc::cpu_register         |
+                                                                             LIR_OprDesc::single_size); }
+  static LIR_Opr double_softfp(int reg1, int reg2) { return (LIR_Opr)((reg2 << LIR_OprDesc::reg1_shift)        |
+                                                                             (reg1 << LIR_OprDesc::reg2_shift) |
+                                                                             LIR_OprDesc::double_type          |
+                                                                             LIR_OprDesc::cpu_register         |
+                                                                             LIR_OprDesc::double_size); }
+#endif // PPC
 
   static LIR_Opr virtual_register(int index, BasicType type) {
     LIR_Opr res;
@@ -623,6 +641,22 @@
                                   LIR_OprDesc::virtual_mask);
         break;
 
+#ifdef __SOFTFP__
+      case T_FLOAT:
+        res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
+                                  LIR_OprDesc::float_type  |
+                                  LIR_OprDesc::cpu_register |
+                                  LIR_OprDesc::single_size |
+                                  LIR_OprDesc::virtual_mask);
+        break;
+      case T_DOUBLE:
+        res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
+                                  LIR_OprDesc::double_type |
+                                  LIR_OprDesc::cpu_register |
+                                  LIR_OprDesc::double_size |
+                                  LIR_OprDesc::virtual_mask);
+        break;
+#else // __SOFTFP__
       case T_FLOAT:
         res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
                                   LIR_OprDesc::float_type           |
@@ -638,7 +672,7 @@
                                             LIR_OprDesc::double_size           |
                                             LIR_OprDesc::virtual_mask);
         break;
-
+#endif // __SOFTFP__
       default:       ShouldNotReachHere(); res = illegalOpr;
     }
 
@@ -650,11 +684,18 @@
 
     // old-style calculation; check if old and new method are equal
     LIR_OprDesc::OprType t = as_OprType(type);
+#ifdef __SOFTFP__
+    LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
+                               t |
+                               LIR_OprDesc::cpu_register |
+                               LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask);
+#else // __SOFTFP__
     LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | t |
                                           ((type == T_FLOAT || type == T_DOUBLE) ?  LIR_OprDesc::fpu_register : LIR_OprDesc::cpu_register) |
                                LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask);
     assert(res == old_res, "old and new method not equal");
-#endif
+#endif // __SOFTFP__
+#endif // ASSERT
 
     return res;
   }
@@ -1306,15 +1347,37 @@
  private:
    Bytecodes::Code _bytecode;
    ConversionStub* _stub;
+#ifdef PPC
+  LIR_Opr _tmp1;
+  LIR_Opr _tmp2;
+#endif
 
  public:
    LIR_OpConvert(Bytecodes::Code code, LIR_Opr opr, LIR_Opr result, ConversionStub* stub)
      : LIR_Op1(lir_convert, opr, result)
      , _stub(stub)
+#ifdef PPC
+     , _tmp1(LIR_OprDesc::illegalOpr())
+     , _tmp2(LIR_OprDesc::illegalOpr())
+#endif
      , _bytecode(code)                           {}
 
+#ifdef PPC
+   LIR_OpConvert(Bytecodes::Code code, LIR_Opr opr, LIR_Opr result, ConversionStub* stub
+                 ,LIR_Opr tmp1, LIR_Opr tmp2)
+     : LIR_Op1(lir_convert, opr, result)
+     , _stub(stub)
+     , _tmp1(tmp1)
+     , _tmp2(tmp2)
+     , _bytecode(code)                           {}
+#endif
+
   Bytecodes::Code bytecode() const               { return _bytecode; }
   ConversionStub* stub() const                   { return _stub; }
+#ifdef PPC
+  LIR_Opr tmp1() const                           { return _tmp1; }
+  LIR_Opr tmp2() const                           { return _tmp2; }
+#endif
 
   virtual void emit_code(LIR_Assembler* masm);
   virtual LIR_OpConvert* as_OpConvert() { return this; }
@@ -1502,6 +1565,9 @@
   LIR_Condition condition() const  {
     assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); return _condition;
   }
+  void set_condition(LIR_Condition condition) {
+    assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove");  _condition = condition;
+  }
 
   void set_fpu_stack_size(int size)              { _fpu_stack_size = size; }
   int  fpu_stack_size() const                    { return _fpu_stack_size; }
@@ -1650,8 +1716,9 @@
   LIR_Opr _tmp2;
 
  public:
-  LIR_OpCompareAndSwap(LIR_Code code, LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2)
-    : LIR_Op(code, LIR_OprFact::illegalOpr, NULL)  // no result, no info
+  LIR_OpCompareAndSwap(LIR_Code code, LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
+                       LIR_Opr t1, LIR_Opr t2, LIR_Opr result)
+    : LIR_Op(code, result, NULL)  // no result, no info
     , _addr(addr)
     , _cmp_value(cmp_value)
     , _new_value(new_value)
@@ -1832,6 +1899,9 @@
 
   void safepoint(LIR_Opr tmp, CodeEmitInfo* info)  { append(new LIR_Op1(lir_safepoint, tmp, info)); }
 
+#ifdef PPC
+  void convert(Bytecodes::Code code, LIR_Opr left, LIR_Opr dst, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_OpConvert(code, left, dst, NULL, tmp1, tmp2)); }
+#endif
   void convert(Bytecodes::Code code, LIR_Opr left, LIR_Opr dst, ConversionStub* stub = NULL/*, bool is_32bit = false*/) { append(new LIR_OpConvert(code, left, dst, stub)); }
 
   void logical_and (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_and,  left, right, dst)); }
@@ -1867,9 +1937,12 @@
     append(new LIR_Op2(lir_cmove, condition, src1, src2, dst));
   }
 
-  void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2);
-  void cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2);
-  void cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2);
+  void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
+                LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr);
+  void cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
+               LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr);
+  void cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
+               LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr);
 
   void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_abs , from, tmp, to)); }
   void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp)                { append(new LIR_Op2(lir_sqrt, from, tmp, to)); }
@@ -1950,7 +2023,7 @@
   }
 
   void load_stack_address_monitor(int monitor_ix, LIR_Opr dst)  { append(new LIR_Op1(lir_monaddr, LIR_OprFact::intConst(monitor_ix), dst)); }
-  void unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, CodeStub* stub);
+  void unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub);
   void lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info);
 
   void set_24bit_fpu()                                               { append(new LIR_Op0(lir_24bit_FPU )); }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -438,6 +438,12 @@
   default: ShouldNotReachHere();
   }
 
+  // JSR 292
+  // Record if this method has MethodHandle invokes.
+  if (op->is_method_handle_invoke()) {
+    compilation()->set_has_method_handle_invokes(true);
+  }
+
 #if defined(X86) && defined(TIERED)
   // C2 leave fpu stack dirty clean it
   if (UseSSE < 2) {
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -31,6 +31,12 @@
 #define __ gen()->lir()->
 #endif
 
+// TODO: ARM - Use some recognizable constant which still fits architectural constraints
+#ifdef ARM
+#define PATCHED_ADDR  (204)
+#else
+#define PATCHED_ADDR  (max_jint)
+#endif
 
 void PhiResolverState::reset(int max_vregs) {
   // Initialize array sizes
@@ -225,13 +231,13 @@
 void LIRItem::load_item_force(LIR_Opr reg) {
   LIR_Opr r = result();
   if (r != reg) {
+#if !defined(ARM) && !defined(E500V2)
     if (r->type() != reg->type()) {
       // moves between different types need an intervening spill slot
-      LIR_Opr tmp = _gen->force_to_spill(r, reg->type());
-      __ move(tmp, reg);
-    } else {
-      __ move(r, reg);
+      r = _gen->force_to_spill(r, reg->type());
     }
+#endif
+    __ move(r, reg);
     _result = reg;
   }
 }
@@ -628,14 +634,14 @@
 }
 
 
-void LIRGenerator::monitor_exit(LIR_Opr object, LIR_Opr lock, LIR_Opr new_hdr, int monitor_no) {
+void LIRGenerator::monitor_exit(LIR_Opr object, LIR_Opr lock, LIR_Opr new_hdr, LIR_Opr scratch, int monitor_no) {
   if (!GenerateSynchronizationCode) return;
   // setup registers
   LIR_Opr hdr = lock;
   lock = new_hdr;
   CodeStub* slow_path = new MonitorExitStub(lock, UseFastLocking, monitor_no);
   __ load_stack_address_monitor(monitor_no, lock);
-  __ unlock_object(hdr, object, lock, slow_path);
+  __ unlock_object(hdr, object, lock, scratch, slow_path);
 }
 
 
@@ -1400,6 +1406,25 @@
   }
   assert(addr->is_register(), "must be a register at this point");
 
+#ifdef ARM
+  // TODO: ARM - move to platform-dependent code
+  LIR_Opr tmp = FrameMap::R14_opr;
+  if (VM_Version::supports_movw()) {
+    __ move((LIR_Opr)card_table_base, tmp);
+  } else {
+    __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp);
+  }
+
+  CardTableModRefBS* ct = (CardTableModRefBS*)_bs;
+  LIR_Address *card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BYTE);
+  if(((int)ct->byte_map_base & 0xff) == 0) {
+    __ move(tmp, card_addr);
+  } else {
+    LIR_Opr tmp_zero = new_register(T_INT);
+    __ move(LIR_OprFact::intConst(0), tmp_zero);
+    __ move(tmp_zero, card_addr);
+  }
+#else // ARM
   LIR_Opr tmp = new_pointer_register();
   if (TwoOperandLIRForm) {
     __ move(addr, tmp);
@@ -1415,6 +1440,7 @@
               new LIR_Address(tmp, load_constant(card_table_base),
                               T_BYTE));
   }
+#endif // ARM
 }
 
 
@@ -1507,7 +1533,7 @@
     // generate_address to try to be smart about emitting the -1.
     // Otherwise the patching code won't know how to find the
     // instruction to patch.
-    address = new LIR_Address(object.result(), max_jint, field_type);
+    address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
   } else {
     address = generate_address(object.result(), x->offset(), field_type);
   }
@@ -1584,7 +1610,7 @@
     // generate_address to try to be smart about emitting the -1.
     // Otherwise the patching code won't know how to find the
     // instruction to patch.
-    address = new LIR_Address(object.result(), max_jint, field_type);
+    address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
   } else {
     address = generate_address(object.result(), x->offset(), field_type);
   }
@@ -1844,6 +1870,8 @@
     }
 #endif
     addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
+#elif defined(ARM)
+    addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
 #else
     if (index_op->is_illegal() || log2_scale == 0) {
 #ifdef _LP64
@@ -1916,6 +1944,7 @@
       __ convert(Bytecodes::_i2l, idx.result(), index_op);
     } else {
 #endif
+      // TODO: ARM also allows embedded shift in the address
       __ move(idx.result(), index_op);
 #ifdef _LP64
     }
@@ -2204,7 +2233,10 @@
     // Assign new location to Local instruction for this local
     Local* local = x->state()->local_at(java_index)->as_Local();
     assert(local != NULL, "Locals for incoming arguments must have been created");
+#ifndef __SOFTFP__
+    // The java calling convention passes double as long and float as int.
     assert(as_ValueType(t)->tag() == local->type()->tag(), "check");
+#endif // __SOFTFP__
     local->set_operand(dest);
     _instruction_for_operand.at_put_grow(dest->vreg_number(), local, NULL);
     java_index += type2size[t];
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -314,7 +314,7 @@
   void logic_op   (Bytecodes::Code code, LIR_Opr dst_reg, LIR_Opr left, LIR_Opr right);
 
   void monitor_enter (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info);
-  void monitor_exit  (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, int monitor_no);
+  void monitor_exit  (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no);
 
   void new_instance    (LIR_Opr  dst, ciInstanceKlass* klass, LIR_Opr  scratch1, LIR_Opr  scratch2, LIR_Opr  scratch3,  LIR_Opr scratch4, LIR_Opr  klass_reg, CodeEmitInfo* info);
 
@@ -338,6 +338,9 @@
   }
   LIR_Address* emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark);
 
+  // the helper for generate_address
+  void add_large_constant(LIR_Opr src, int c, LIR_Opr dest);
+
   // machine preferences and characteristics
   bool can_inline_as_constant(Value i) const;
   bool can_inline_as_constant(LIR_Const* c) const;
@@ -393,6 +396,10 @@
     return l;
   }
 
+#ifdef __SOFTFP__
+  void do_soft_float_compare(If *x);
+#endif // __SOFTFP__
+
   void init();
 
   SwitchRangeArray* create_lookup_ranges(TableSwitch* x);
@@ -444,6 +451,7 @@
   static LIR_Opr remOutOpr();
   static LIR_Opr shiftCountOpr();
   LIR_Opr syncTempOpr();
+  LIR_Opr atomicLockOpr();
 
   // returns a register suitable for saving the thread in a
   // call_runtime_leaf if one is needed.
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -169,7 +169,11 @@
 }
 
 bool LinearScan::is_virtual_cpu_interval(const Interval* i) {
+#if defined(__SOFTFP__) || defined(E500V2)
+  return i->reg_num() >= LIR_OprDesc::vreg_base;
+#else
   return i->reg_num() >= LIR_OprDesc::vreg_base && (i->type() != T_FLOAT && i->type() != T_DOUBLE);
+#endif // __SOFTFP__ or E500V2
 }
 
 bool LinearScan::is_precolored_fpu_interval(const Interval* i) {
@@ -177,7 +181,11 @@
 }
 
 bool LinearScan::is_virtual_fpu_interval(const Interval* i) {
+#if defined(__SOFTFP__) || defined(E500V2)
+  return false;
+#else
   return i->reg_num() >= LIR_OprDesc::vreg_base && (i->type() == T_FLOAT || i->type() == T_DOUBLE);
+#endif // __SOFTFP__ or E500V2
 }
 
 bool LinearScan::is_in_fpu_register(const Interval* i) {
@@ -2010,12 +2018,18 @@
         return LIR_OprFact::single_cpu_oop(assigned_reg);
       }
 
+#ifdef __SOFTFP__
+      case T_FLOAT:  // fall through
+#endif // __SOFTFP__
       case T_INT: {
         assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register");
         assert(interval->assigned_regHi() == any_reg, "must not have hi register");
         return LIR_OprFact::single_cpu(assigned_reg);
       }
 
+#ifdef __SOFTFP__
+      case T_DOUBLE:  // fall through
+#endif // __SOFTFP__
       case T_LONG: {
         int assigned_regHi = interval->assigned_regHi();
         assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register");
@@ -2033,7 +2047,7 @@
 #ifdef _LP64
         return LIR_OprFact::double_cpu(assigned_reg, assigned_reg);
 #else
-#ifdef SPARC
+#if defined(SPARC) || defined(PPC)
         return LIR_OprFact::double_cpu(assigned_regHi, assigned_reg);
 #else
         return LIR_OprFact::double_cpu(assigned_reg, assigned_regHi);
@@ -2041,6 +2055,7 @@
 #endif // LP64
       }
 
+#ifndef __SOFTFP__
       case T_FLOAT: {
 #ifdef X86
         if (UseSSE >= 1) {
@@ -2069,6 +2084,11 @@
         assert(interval->assigned_regHi() >= pd_first_fpu_reg && interval->assigned_regHi() <= pd_last_fpu_reg, "no fpu register");
         assert(assigned_reg % 2 == 0 && assigned_reg + 1 == interval->assigned_regHi(), "must be sequential and even");
         LIR_Opr result = LIR_OprFact::double_fpu(interval->assigned_regHi() - pd_first_fpu_reg, assigned_reg - pd_first_fpu_reg);
+#elif defined(ARM)
+        assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register");
+        assert(interval->assigned_regHi() >= pd_first_fpu_reg && interval->assigned_regHi() <= pd_last_fpu_reg, "no fpu register");
+        assert(assigned_reg % 2 == 0 && assigned_reg + 1 == interval->assigned_regHi(), "must be sequential and even");
+        LIR_Opr result = LIR_OprFact::double_fpu(assigned_reg - pd_first_fpu_reg, interval->assigned_regHi() - pd_first_fpu_reg);
 #else
         assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register");
         assert(interval->assigned_regHi() == any_reg, "must not have hi register (double fpu values are stored in one register on Intel)");
@@ -2076,6 +2096,7 @@
 #endif
         return result;
       }
+#endif // __SOFTFP__
 
       default: {
         ShouldNotReachHere();
@@ -2638,6 +2659,12 @@
 #ifdef SPARC
       assert(opr->fpu_regnrLo() == opr->fpu_regnrHi() + 1, "assumed in calculation (only fpu_regnrHi is used)");
 #endif
+#ifdef ARM
+      assert(opr->fpu_regnrHi() == opr->fpu_regnrLo() + 1, "assumed in calculation (only fpu_regnrLo is used)");
+#endif
+#ifdef PPC
+      assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrHi is used)");
+#endif
 
       VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrHi());
 #ifdef _LP64
@@ -6135,6 +6162,17 @@
             assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
             LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;
 
+            LIR_Op2* prev_cmp = NULL;
+
+            for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
+              prev_op = instructions->at(j);
+              if(prev_op->code() == lir_cmp) {
+                assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
+                prev_cmp = (LIR_Op2*)prev_op;
+                assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
+              }
+            }
+            assert(prev_cmp != NULL, "should have found comp instruction for branch");
             if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
 
               TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
@@ -6142,6 +6180,7 @@
               // eliminate a conditional branch to the immediate successor
               prev_branch->change_block(last_branch->block());
               prev_branch->negate_cond();
+              prev_cmp->set_condition(prev_branch->cond());
               instructions->truncate(instructions->length() - 1);
             }
           }
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -144,7 +144,7 @@
 #ifndef TIERED
     case counter_overflow_id: // Not generated outside the tiered world
 #endif
-#ifdef SPARC
+#if defined(SPARC) || defined(PPC)
     case handle_exception_nofpu_id:  // Unused on sparc
 #endif
       break;
@@ -240,7 +240,8 @@
 
 #undef FUNCTION_CASE
 
-  return "<unknown function>";
+  // Soft float adds more runtime names.
+  return pd_name_for_address(entry);
 }
 
 
@@ -896,7 +897,10 @@
           } else {
             // patch the instruction <move reg, klass>
             NativeMovConstReg* n_copy = nativeMovConstReg_at(copy_buff);
-            assert(n_copy->data() == 0, "illegal init value");
+
+            assert(n_copy->data() == 0 ||
+                   n_copy->data() == (int)Universe::non_oop_word(),
+                   "illegal init value");
             assert(load_klass() != NULL, "klass not set");
             n_copy->set_data((intx) (load_klass()));
 
@@ -904,7 +908,7 @@
               Disassembler::decode(copy_buff, copy_buff + *byte_count, tty);
             }
 
-#ifdef SPARC
+#if defined(SPARC) || defined(PPC)
             // Update the oop location in the nmethod with the proper
             // oop.  When the code was generated, a NULL was stuffed
             // in the oop table and that table needs to be update to
@@ -934,6 +938,14 @@
         if (do_patch) {
           // replace instructions
           // first replace the tail, then the call
+#ifdef ARM
+          if(stub_id == Runtime1::load_klass_patching_id && !VM_Version::supports_movw()) {
+            copy_buff -= *byte_count;
+            NativeMovConstReg* n_copy2 = nativeMovConstReg_at(copy_buff);
+            n_copy2->set_data((intx) (load_klass()), instr_pc);
+          }
+#endif
+
           for (int i = NativeCall::instruction_size; i < *byte_count; i++) {
             address ptr = copy_buff + i;
             int a_byte = (*ptr) & 0xFF;
@@ -961,6 +973,12 @@
             relocInfo::change_reloc_info_for_address(&iter2, (address) instr_pc2,
                                                      relocInfo::none, relocInfo::oop_type);
 #endif
+#ifdef PPC
+          { address instr_pc2 = instr_pc + NativeMovConstReg::lo_offset;
+            RelocIterator iter2(nm, instr_pc2, instr_pc2 + 1);
+            relocInfo::change_reloc_info_for_address(&iter2, (address) instr_pc2, relocInfo::none, relocInfo::oop_type);
+          }
+#endif
           }
 
         } else {
--- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -159,6 +159,9 @@
   static const char* name_for (StubID id);
   static const char* name_for_address(address entry);
 
+  // platform might add runtime names.
+  static const char* pd_name_for_address(address entry);
+
   // method tracing
   static void trace_block_entry(jint block_id);
 
--- a/hotspot/src/share/vm/ci/ciField.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/ci/ciField.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -339,7 +339,7 @@
   if (_type != NULL) _type->print_name();
   else               tty->print("(reference)");
   tty->print(" is_constant=%s", bool_to_str(_is_constant));
-  if (_is_constant) {
+  if (_is_constant && is_static()) {
     tty->print(" constant_value=");
     _constant_value.print();
   }
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -403,8 +403,9 @@
     instanceKlass* ik = get_instanceKlass();
     int max_n_fields = ik->fields()->length()/instanceKlass::next_offset;
 
+    Arena* arena = curEnv->arena();
     _non_static_fields =
-      new (curEnv->arena()) GrowableArray<ciField*>(max_n_fields);
+      new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL);
     NonStaticFieldFiller filler(curEnv, _non_static_fields);
     ik->do_nonstatic_fields(&filler);
   }
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -55,10 +55,10 @@
   _exception_handlers = NULL;
   _liveness           = NULL;
   _method_blocks = NULL;
-#ifdef COMPILER2
+#if defined(COMPILER2) || defined(SHARK)
   _flow               = NULL;
   _bcea               = NULL;
-#endif // COMPILER2
+#endif // COMPILER2 || SHARK
 
   ciEnv *env = CURRENT_ENV;
   if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) {
@@ -123,10 +123,10 @@
   _can_be_statically_bound = false;
   _method_blocks = NULL;
   _method_data = NULL;
-#ifdef COMPILER2
+#if defined(COMPILER2) || defined(SHARK)
   _flow = NULL;
   _bcea = NULL;
-#endif // COMPILER2
+#endif // COMPILER2 || SHARK
 }
 
 
@@ -229,6 +229,20 @@
 }
 
 
+#ifdef SHARK
+// ------------------------------------------------------------------
+// ciMethod::itable_index
+//
+// Get the position of this method's entry in the itable, if any.
+int ciMethod::itable_index() {
+  check_is_loaded();
+  assert(holder()->is_linked(), "must be linked");
+  VM_ENTRY_MARK;
+  return klassItable::compute_itable_index(get_methodOop());
+}
+#endif // SHARK
+
+
 // ------------------------------------------------------------------
 // ciMethod::native_entry
 //
@@ -294,34 +308,34 @@
 // ------------------------------------------------------------------
 // ciMethod::get_flow_analysis
 ciTypeFlow* ciMethod::get_flow_analysis() {
-#ifdef COMPILER2
+#if defined(COMPILER2) || defined(SHARK)
   if (_flow == NULL) {
     ciEnv* env = CURRENT_ENV;
     _flow = new (env->arena()) ciTypeFlow(env, this);
     _flow->do_flow();
   }
   return _flow;
-#else // COMPILER2
+#else // COMPILER2 || SHARK
   ShouldNotReachHere();
   return NULL;
-#endif // COMPILER2
+#endif // COMPILER2 || SHARK
 }
 
 
 // ------------------------------------------------------------------
 // ciMethod::get_osr_flow_analysis
 ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) {
-#ifdef COMPILER2
+#if defined(COMPILER2) || defined(SHARK)
   // OSR entry points are always place after a call bytecode of some sort
   assert(osr_bci >= 0, "must supply valid OSR entry point");
   ciEnv* env = CURRENT_ENV;
   ciTypeFlow* flow = new (env->arena()) ciTypeFlow(env, this, osr_bci);
   flow->do_flow();
   return flow;
-#else // COMPILER2
+#else // COMPILER2 || SHARK
   ShouldNotReachHere();
   return NULL;
-#endif // COMPILER2
+#endif // COMPILER2 || SHARK
 }
 
 // ------------------------------------------------------------------
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -70,7 +70,7 @@
 
   // Optional liveness analyzer.
   MethodLiveness* _liveness;
-#ifdef COMPILER2
+#if defined(COMPILER2) || defined(SHARK)
   ciTypeFlow*         _flow;
   BCEscapeAnalyzer*   _bcea;
 #endif
@@ -141,6 +141,9 @@
 
   // Runtime information.
   int           vtable_index();
+#ifdef SHARK
+  int           itable_index();
+#endif // SHARK
   address       native_entry();
   address       interpreter_entry();
 
--- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -252,7 +252,7 @@
                           _arena(arena), _num_blocks(0), _code_size(meth->code_size()) {
   int block_estimate = _code_size / 8;
 
-  _blocks =  new(_arena) GrowableArray<ciBlock *>(block_estimate);
+  _blocks =  new(_arena) GrowableArray<ciBlock *>(_arena, block_estimate, 0, NULL);
   int b2bsize = _code_size * sizeof(ciBlock **);
   _bci_to_block = (ciBlock **) arena->Amalloc(b2bsize);
   Copy::zero_to_words((HeapWord*) _bci_to_block, b2bsize / sizeof(HeapWord));
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -2591,7 +2591,7 @@
                                StateVector* temp_vector,
                                JsrSet* temp_set) {
   int dft_len = 100;
-  GrowableArray<Block*> stk(arena(), dft_len, 0, NULL);
+  GrowableArray<Block*> stk(dft_len);
 
   ciBlock* dummy = _methodBlocks->make_dummy_block();
   JsrSet* root_set = new JsrSet(NULL, 0);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -62,6 +62,7 @@
   ClassFileStream cfs1 = *cfs0;
   ClassFileStream* cfs = &cfs1;
 #ifdef ASSERT
+  assert(cfs->allocated_on_stack(),"should be local");
   u1* old_current = cfs0->current();
 #endif
 
--- a/hotspot/src/share/vm/classfile/verificationType.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/classfile/verificationType.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -70,7 +70,9 @@
   } else if (is_array() && from.is_array()) {
     VerificationType comp_this = get_component(CHECK_false);
     VerificationType comp_from = from.get_component(CHECK_false);
-    return comp_this.is_assignable_from(comp_from, context, CHECK_false);
+    if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
+      return comp_this.is_assignable_from(comp_from, context, CHECK_false);
+    }
   }
   return false;
 }
@@ -98,7 +100,7 @@
         CHECK_(VerificationType::bogus_type()));
       return VerificationType::reference_type(component);
     default:
-      ShouldNotReachHere();
+      // Met an invalid type signature, e.g. [X
       return VerificationType::bogus_type();
   }
 }
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1847,12 +1847,8 @@
   if (type == VerificationType::uninitialized_this_type()) {
     // The method must be an <init> method of either this class, or one of its
     // superclasses
-    klassOop oop = current_class()();
-    Klass* klass = oop->klass_part();
-    while (klass != NULL && ref_class_type.name() != klass->name()) {
-      klass = klass->super()->klass_part();
-    }
-    if (klass == NULL) {
+    if (ref_class_type.name() != current_class()->name() &&
+        !name_in_supers(ref_class_type.name(), current_class())) {
       verify_error(bci, "Bad <init> method call");
       return;
     }
--- a/hotspot/src/share/vm/code/codeBlob.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/code/codeBlob.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -564,72 +564,53 @@
   ShouldNotReachHere();
 }
 
-#ifndef PRODUCT
-
-void CodeBlob::print() const {
-  tty->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", this);
-  tty->print_cr("Framesize: %d", _frame_size);
+void CodeBlob::print_on(outputStream* st) const {
+  st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", this);
+  st->print_cr("Framesize: %d", _frame_size);
 }
 
-
 void CodeBlob::print_value_on(outputStream* st) const {
   st->print_cr("[CodeBlob]");
 }
 
-#endif
-
 void BufferBlob::verify() {
   // unimplemented
 }
 
-#ifndef PRODUCT
-
-void BufferBlob::print() const {
-  CodeBlob::print();
-  print_value_on(tty);
+void BufferBlob::print_on(outputStream* st) const {
+  CodeBlob::print_on(st);
+  print_value_on(st);
 }
 
-
 void BufferBlob::print_value_on(outputStream* st) const {
   st->print_cr("BufferBlob (" INTPTR_FORMAT  ") used for %s", this, name());
 }
 
-
-#endif
-
 void RuntimeStub::verify() {
   // unimplemented
 }
 
-#ifndef PRODUCT
-
-void RuntimeStub::print() const {
-  CodeBlob::print();
-  tty->print("Runtime Stub (" INTPTR_FORMAT "): ", this);
-  tty->print_cr(name());
-  Disassembler::decode((CodeBlob*)this);
+void RuntimeStub::print_on(outputStream* st) const {
+  CodeBlob::print_on(st);
+  st->print("Runtime Stub (" INTPTR_FORMAT "): ", this);
+  st->print_cr(name());
+  Disassembler::decode((CodeBlob*)this, st);
 }
 
-
 void RuntimeStub::print_value_on(outputStream* st) const {
   st->print("RuntimeStub (" INTPTR_FORMAT "): ", this); st->print(name());
 }
 
-#endif
-
 void SingletonBlob::verify() {
   // unimplemented
 }
 
-#ifndef PRODUCT
-
-void SingletonBlob::print() const {
-  CodeBlob::print();
-  tty->print_cr(name());
-  Disassembler::decode((CodeBlob*)this);
+void SingletonBlob::print_on(outputStream* st) const {
+  CodeBlob::print_on(st);
+  st->print_cr(name());
+  Disassembler::decode((CodeBlob*)this, st);
 }
 
-
 void SingletonBlob::print_value_on(outputStream* st) const {
   st->print_cr(name());
 }
@@ -637,5 +618,3 @@
 void DeoptimizationBlob::print_value_on(outputStream* st) const {
   st->print_cr("Deoptimization (frame not available)");
 }
-
-#endif // PRODUCT
--- a/hotspot/src/share/vm/code/codeBlob.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/code/codeBlob.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -163,8 +163,9 @@
 
   // Debugging
   virtual void verify();
-  virtual void print() const                     PRODUCT_RETURN;
-  virtual void print_value_on(outputStream* st) const PRODUCT_RETURN;
+  void print() const                             { print_on(tty); }
+  virtual void print_on(outputStream* st) const;
+  virtual void print_value_on(outputStream* st) const;
 
   // Print the comment associated with offset on stream, if there is one
   virtual void print_block_comment(outputStream* stream, address block_begin) {
@@ -209,8 +210,8 @@
   bool is_alive() const                          { return true; }
 
   void verify();
-  void print() const                             PRODUCT_RETURN;
-  void print_value_on(outputStream* st) const    PRODUCT_RETURN;
+  void print_on(outputStream* st) const;
+  void print_value_on(outputStream* st) const;
 };
 
 
@@ -292,8 +293,8 @@
   bool is_alive() const                          { return true; }
 
   void verify();
-  void print() const                             PRODUCT_RETURN;
-  void print_value_on(outputStream* st) const    PRODUCT_RETURN;
+  void print_on(outputStream* st) const;
+  void print_value_on(outputStream* st) const;
 };
 
 
@@ -317,8 +318,8 @@
    bool is_alive() const                         { return true; }
 
    void verify(); // does nothing
-   void print() const                            PRODUCT_RETURN;
-   void print_value_on(outputStream* st) const   PRODUCT_RETURN;
+   void print_on(outputStream* st) const;
+   void print_value_on(outputStream* st) const;
 };
 
 
@@ -373,7 +374,7 @@
   void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ }
 
   // Printing
-  void print_value_on(outputStream* st) const PRODUCT_RETURN;
+  void print_value_on(outputStream* st) const;
 
   address unpack() const                         { return instructions_begin() + _unpack_offset;           }
   address unpack_with_exception() const          { return instructions_begin() + _unpack_with_exception;   }
--- a/hotspot/src/share/vm/code/nmethod.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -65,6 +65,11 @@
   if (is_native_method()) return false;
   return compiler()->is_c2();
 }
+bool nmethod::is_compiled_by_shark() const {
+  if (is_native_method()) return false;
+  assert(compiler() != NULL, "must be");
+  return compiler()->is_shark();
+}
 
 
 
@@ -1353,6 +1358,10 @@
     CodeCache::remove_saved_code(this);
   }
 
+#ifdef SHARK
+  ((SharkCompiler *) compiler())->free_compiled_method(instructions_begin());
+#endif // SHARK
+
   ((CodeBlob*)(this))->flush();
 
   CodeCache::free(this);
@@ -1769,6 +1778,7 @@
 // Method that knows how to preserve outgoing arguments at call. This method must be
 // called with a frame corresponding to a Java invoke
 void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
+#ifndef SHARK
   if (!method()->is_native()) {
     SimpleScopeDesc ssd(this, fr.pc());
     Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci());
@@ -1776,6 +1786,7 @@
     symbolOop signature = call->signature();
     fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
   }
+#endif // !SHARK
 }
 
 
@@ -2279,6 +2290,8 @@
     tty->print("(c1) ");
   } else if (is_compiled_by_c2()) {
     tty->print("(c2) ");
+  } else if (is_compiled_by_shark()) {
+    tty->print("(shark) ");
   } else {
     tty->print("(nm) ");
   }
@@ -2472,8 +2485,12 @@
   if (block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
   if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
   if (block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
-  if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
+
+  if (has_method_handle_invokes())
+    if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
+
   if (block_begin == consts_begin())            stream->print_cr("[Constants]");
+
   if (block_begin == entry_point()) {
     methodHandle m = method();
     if (m.not_null()) {
--- a/hotspot/src/share/vm/code/nmethod.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -329,6 +329,7 @@
 
   bool is_compiled_by_c1() const;
   bool is_compiled_by_c2() const;
+  bool is_compiled_by_shark() const;
 
   // boundaries for different parts
   address code_begin            () const          { return _entry_point; }
@@ -606,6 +607,8 @@
   void print_nul_chk_table()                      PRODUCT_RETURN;
   void print_nmethod(bool print_code);
 
+  // need to re-define this from CodeBlob else the overload hides it
+  virtual void print_on(outputStream* st) const { CodeBlob::print_on(st); }
   void print_on(outputStream* st, const char* title) const;
 
   // Logging
--- a/hotspot/src/share/vm/code/vtableStubs.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -67,8 +67,8 @@
 }
 
 
-void VtableStub::print() {
-  tty->print("vtable stub (index = %d, receiver_location = %d, code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "[)",
+void VtableStub::print_on(outputStream* st) const {
+  st->print("vtable stub (index = %d, receiver_location = %d, code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "[)",
              index(), receiver_location(), code_begin(), code_end());
 }
 
--- a/hotspot/src/share/vm/code/vtableStubs.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/code/vtableStubs.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -86,7 +86,9 @@
   bool is_abstract_method_error(address epc)     { return epc == code_begin()+_ame_offset; }
   bool is_null_pointer_exception(address epc)    { return epc == code_begin()+_npe_offset; }
 
-  void print();
+  void print_on(outputStream* st) const;
+  void print() const                             { print_on(tty); }
+
 };
 
 
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,18 +45,26 @@
   // Missing feature tests
   virtual bool supports_native()                 { return true; }
   virtual bool supports_osr   ()                 { return true; }
-#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2))
+#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK))
   virtual bool is_c1   ()                        { return false; }
   virtual bool is_c2   ()                        { return false; }
+  virtual bool is_shark()                        { return false; }
 #else
 #ifdef COMPILER1
   bool is_c1   ()                                { return true; }
   bool is_c2   ()                                { return false; }
+  bool is_shark()                                { return false; }
 #endif // COMPILER1
 #ifdef COMPILER2
   bool is_c1   ()                                { return false; }
   bool is_c2   ()                                { return true; }
+  bool is_shark()                                { return false; }
 #endif // COMPILER2
+#ifdef SHARK
+  bool is_c1   ()                                { return false; }
+  bool is_c2   ()                                { return false; }
+  bool is_shark()                                { return true; }
+#endif // SHARK
 #endif // TIERED
 
   // Customization
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -568,6 +568,14 @@
 #endif
 #endif // COMPILER2
 
+#ifdef SHARK
+#if defined(COMPILER1) || defined(COMPILER2)
+#error "Can't use COMPILER1 or COMPILER2 with shark"
+#endif
+  _compilers[0] = new SharkCompiler();
+  _compilers[1] = _compilers[0];
+#endif
+
   // Initialize the CompileTask free list
   _task_free_list = NULL;
 
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,7 @@
 address decode_env::decode_instructions(address start, address end) {
   _start = start; _end = end;
 
-  assert((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment() == 0), "misaligned insn addr");
+  assert(((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment()) == 0), "misaligned insn addr");
 
   const int show_bytes = false; // for disassembler debugging
 
@@ -423,8 +423,14 @@
   env.output()->print_cr("Decoding compiled method " INTPTR_FORMAT ":", nm);
   env.output()->print_cr("Code:");
 
+#ifdef SHARK
+  SharkEntry* entry = (SharkEntry *) nm->instructions_begin();
+  unsigned char* p = entry->code_start();
+  unsigned char* end = entry->code_limit();
+#else
   unsigned char* p = nm->instructions_begin();
   unsigned char* end = nm->instructions_end();
+#endif // SHARK
 
   // If there has been profiling, print the buckets.
   if (FlatProfiler::bucket_start_for(p) != NULL) {
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -158,13 +158,18 @@
   // The line below is the worst bit of C++ hackery I've ever written
   // (Detlefs, 11/23).  You should think of it as equivalent to
   // "_regions(100, true)": initialize the growable array and inform it
-  // that it should allocate its elem array(s) on the C heap.  The first
-  // argument, however, is actually a comma expression (new-expr, 100).
-  // The purpose of the new_expr is to inform the growable array that it
-  // is *already* allocated on the C heap: it uses the placement syntax to
-  // keep it from actually doing any allocation.
-  _markedRegions((ResourceObj::operator new (sizeof(GrowableArray<HeapRegion*>),
-                                             (void*)&_markedRegions,
+  // that it should allocate its elem array(s) on the C heap.
+  //
+  // The first argument, however, is actually a comma expression
+  // (set_allocation_type(this, C_HEAP), 100). The purpose of the
+  // set_allocation_type() call is to replace the default allocation
+  // type for embedded objects STACK_OR_EMBEDDED with C_HEAP. It will
+  // allow to pass the assert in GenericGrowableArray() which checks
+  // that a growable array object must be on C heap if elements are.
+  //
+  // Note: containing object is allocated on C heap since it is CHeapObj.
+  //
+  _markedRegions((ResourceObj::set_allocation_type((address)&_markedRegions,
                                              ResourceObj::C_HEAP),
                   100),
                  true),
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -42,14 +42,19 @@
   // The line below is the worst bit of C++ hackery I've ever written
   // (Detlefs, 11/23).  You should think of it as equivalent to
   // "_regions(100, true)": initialize the growable array and inform it
-  // that it should allocate its elem array(s) on the C heap.  The first
-  // argument, however, is actually a comma expression (new-expr, 100).
-  // The purpose of the new_expr is to inform the growable array that it
-  // is *already* allocated on the C heap: it uses the placement syntax to
-  // keep it from actually doing any allocation.
-  _regions((ResourceObj::operator new (sizeof(GrowableArray<HeapRegion*>),
-                                       (void*)&_regions,
-                                       ResourceObj::C_HEAP),
+  // that it should allocate its elem array(s) on the C heap.
+  //
+  // The first argument, however, is actually a comma expression
+  // (set_allocation_type(this, C_HEAP), 100). The purpose of the
+  // set_allocation_type() call is to replace the default allocation
+  // type for embedded objects STACK_OR_EMBEDDED with C_HEAP. It will
+  // allow to pass the assert in GenericGrowableArray() which checks
+  // that a growable array object must be on C heap if elements are.
+  //
+  // Note: containing object is allocated on C heap since it is CHeapObj.
+  //
+  _regions((ResourceObj::set_allocation_type((address)&_regions,
+                                             ResourceObj::C_HEAP),
             (int)max_size),
            true),
   _next_rr_candidate(0),
--- a/hotspot/src/share/vm/includeDB_compiler1	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/includeDB_compiler1	Thu Sep 02 12:17:21 2010 -0700
@@ -252,6 +252,7 @@
 c1_LIRGenerator.cpp                     ciInstance.hpp
 c1_LIRGenerator.cpp                     heapRegion.hpp
 c1_LIRGenerator.cpp                     sharedRuntime.hpp
+c1_LIRGenerator.cpp                     stubRoutines.hpp
 
 c1_LIRGenerator.hpp                     c1_Instruction.hpp
 c1_LIRGenerator.hpp                     c1_LIR.hpp
@@ -270,6 +271,8 @@
 c1_LIRGenerator_<arch>.cpp             ciTypeArrayKlass.hpp
 c1_LIRGenerator_<arch>.cpp             sharedRuntime.hpp
 c1_LIRGenerator_<arch>.cpp             vmreg_<arch>.inline.hpp
+c1_LIRGenerator_<arch>.cpp             stubRoutines.hpp
+
 
 c1_LinearScan.cpp                       bitMap.inline.hpp
 c1_LinearScan.cpp                       c1_CFGPrinter.hpp
@@ -413,6 +416,7 @@
 compileBroker.cpp                       c1_Compiler.hpp
 
 frame_<arch>.cpp                        c1_Runtime1.hpp
+frame_<arch>.cpp                        vframeArray.hpp
 
 globals.cpp                             c1_globals.hpp
 
--- a/hotspot/src/share/vm/includeDB_compiler2	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/includeDB_compiler2	Thu Sep 02 12:17:21 2010 -0700
@@ -911,6 +911,7 @@
 reg_split.cpp                           addnode.hpp
 reg_split.cpp                           allocation.inline.hpp
 reg_split.cpp                           callnode.hpp
+reg_split.cpp                           c2compiler.hpp
 reg_split.cpp                           cfgnode.hpp
 reg_split.cpp                           chaitin.hpp
 reg_split.cpp                           loopnode.hpp
--- a/hotspot/src/share/vm/includeDB_core	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/includeDB_core	Thu Sep 02 12:17:21 2010 -0700
@@ -284,6 +284,7 @@
 atomic_<os_arch>.inline.hpp             atomic.hpp
 atomic_<os_arch>.inline.hpp             os.hpp
 atomic_<os_arch>.inline.hpp             vm_version_<arch>.hpp
+atomic_<os_arch>.inline.hpp             orderAccess_<os_arch>.inline.hpp
 
 // attachListener is jck optional, put cpp deps in includeDB_features
 
@@ -1734,6 +1735,7 @@
 genCollectedHeap.cpp                    space.hpp
 genCollectedHeap.cpp                    symbolTable.hpp
 genCollectedHeap.cpp                    systemDictionary.hpp
+genCollectedHeap.cpp                    vmError.hpp
 genCollectedHeap.cpp                    vmGCOperations.hpp
 genCollectedHeap.cpp                    vmSymbols.hpp
 genCollectedHeap.cpp                    vmThread.hpp
@@ -3230,6 +3232,7 @@
 os.cpp                                  events.hpp
 os.cpp                                  frame.inline.hpp
 os.cpp                                  hpi.hpp
+os.cpp					icBuffer.hpp
 os.cpp                                  interfaceSupport.hpp
 os.cpp                                  interpreter.hpp
 os.cpp                                  java.hpp
@@ -3241,6 +3244,7 @@
 os.cpp                                  oop.inline.hpp
 os.cpp                                  os.hpp
 os.cpp                                  os_<os_family>.inline.hpp
+os.cpp	                                privilegedStack.hpp
 os.cpp                                  stubRoutines.hpp
 os.cpp                                  systemDictionary.hpp
 os.cpp                                  threadService.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/includeDB_shark	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,371 @@
+//
+// Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+// Copyright 2008, 2009, 2010 Red Hat, Inc.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//
+//
+
+// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
+
+ciMethod.cpp                            ciTypeFlow.hpp
+ciMethod.cpp                            methodOop.hpp
+
+ciTypeFlow.cpp                          allocation.inline.hpp
+ciTypeFlow.cpp                          bytecode.hpp
+ciTypeFlow.cpp                          bytecodes.hpp
+ciTypeFlow.cpp                          ciConstant.hpp
+ciTypeFlow.cpp                          ciField.hpp
+ciTypeFlow.cpp                          ciMethod.hpp
+ciTypeFlow.cpp                          ciMethodData.hpp
+ciTypeFlow.cpp                          ciObjArrayKlass.hpp
+ciTypeFlow.cpp                          ciStreams.hpp
+ciTypeFlow.cpp                          ciTypeArrayKlass.hpp
+ciTypeFlow.cpp                          ciTypeFlow.hpp
+ciTypeFlow.cpp                          compileLog.hpp
+ciTypeFlow.cpp                          deoptimization.hpp
+ciTypeFlow.cpp                          growableArray.hpp
+ciTypeFlow.cpp                          shark_globals.hpp
+
+ciTypeFlow.hpp                          ciEnv.hpp
+ciTypeFlow.hpp                          ciKlass.hpp
+ciTypeFlow.hpp                          ciMethodBlocks.hpp
+
+cppInterpreter_<arch>.cpp               shark_globals.hpp
+
+compileBroker.cpp                       sharkCompiler.hpp
+
+disassembler.cpp                        sharkEntry.hpp
+
+globals.hpp                             shark_globals_<arch>.hpp
+
+globals.cpp                             shark_globals.hpp
+
+llvmValue.hpp                           llvmHeaders.hpp
+llvmValue.hpp                           sharkContext.hpp
+llvmValue.hpp                           sharkType.hpp
+
+nmethod.cpp                             sharkCompiler.hpp
+
+sharedRuntime_<arch>.cpp                compileBroker.hpp
+sharedRuntime_<arch>.cpp                sharkCompiler.hpp
+
+shark_globals.cpp                       shark_globals.hpp
+
+shark_globals.hpp                       shark_globals_<arch>.hpp
+shark_globals.hpp                       globals.hpp
+
+sharkBlock.cpp                          debug.hpp
+sharkBlock.cpp                          bytecodes.hpp
+sharkBlock.cpp                          llvmHeaders.hpp
+sharkBlock.cpp                          llvmValue.hpp
+sharkBlock.cpp                          shark_globals.hpp
+sharkBlock.cpp                          sharkBlock.hpp
+sharkBlock.cpp                          sharkBuilder.hpp
+sharkBlock.cpp                          sharkConstant.hpp
+sharkBlock.cpp                          sharkState.hpp
+sharkBlock.cpp                          sharkValue.hpp
+
+sharkBlock.hpp                          allocation.hpp
+sharkBlock.hpp                          ciMethod.hpp
+sharkBlock.hpp                          ciStreams.hpp
+sharkBlock.hpp                          debug.hpp
+sharkBlock.hpp                          llvmHeaders.hpp
+sharkBlock.hpp                          sharkBuilder.hpp
+sharkBlock.hpp                          sharkConstant.hpp
+sharkBlock.hpp                          sharkInvariants.hpp
+sharkBlock.hpp                          sharkState.hpp
+sharkBlock.hpp                          sharkValue.hpp
+
+sharkBuilder.cpp                        ciMethod.hpp
+sharkBuilder.cpp                        debug.hpp
+sharkBuilder.cpp                        llvmHeaders.hpp
+sharkBuilder.cpp                        llvmValue.hpp
+sharkBuilder.cpp                        methodOop.hpp
+sharkBuilder.cpp                        os.hpp
+sharkBuilder.cpp                        resourceArea.hpp
+sharkBuilder.cpp                        llvmHeaders.hpp
+sharkBuilder.cpp                        sharkBuilder.hpp
+sharkBuilder.cpp                        sharkContext.hpp
+sharkBuilder.cpp                        sharkRuntime.hpp
+sharkBuilder.cpp                        synchronizer.hpp
+sharkBuilder.cpp                        thread.hpp
+
+sharkBuilder.hpp                        barrierSet.hpp
+sharkBuilder.hpp                        cardTableModRefBS.hpp
+sharkBuilder.hpp                        ciType.hpp
+sharkBuilder.hpp                        debug.hpp
+sharkBuilder.hpp                        llvmHeaders.hpp
+sharkBuilder.hpp                        llvmValue.hpp
+sharkBuilder.hpp                        sizes.hpp
+sharkBuilder.hpp                        sharkCodeBuffer.hpp
+sharkBuilder.hpp                        sharkType.hpp
+sharkBuilder.hpp                        sharkValue.hpp
+sharkBuilder.hpp                        sharkEntry.hpp
+
+sharkCacheDecache.cpp                   ciMethod.hpp
+sharkCacheDecache.cpp                   debugInfoRec.hpp
+sharkCacheDecache.cpp                   llvmValue.hpp
+sharkCacheDecache.cpp                   sharkBuilder.hpp
+sharkCacheDecache.cpp                   sharkCacheDecache.hpp
+sharkCacheDecache.cpp                   sharkFunction.hpp
+sharkCacheDecache.cpp                   sharkState.hpp
+
+sharkCacheDecache.hpp                   ciMethod.hpp
+sharkCacheDecache.hpp                   debugInfoRec.hpp
+sharkCacheDecache.hpp                   sharkBuilder.hpp
+sharkCacheDecache.hpp                   sharkFunction.hpp
+sharkCacheDecache.hpp                   sharkStateScanner.hpp
+
+sharkCodeBuffer.hpp                     allocation.hpp
+sharkCodeBuffer.hpp                     codeBuffer.hpp
+sharkCodeBuffer.hpp                     llvmHeaders.hpp
+
+sharkCompiler.cpp                       abstractCompiler.hpp
+sharkCompiler.cpp                       ciEnv.hpp
+sharkCompiler.cpp                       ciMethod.hpp
+sharkCompiler.cpp                       debug.hpp
+sharkCompiler.cpp                       debugInfoRec.hpp
+sharkCompiler.cpp                       dependencies.hpp
+sharkCompiler.cpp                       exceptionHandlerTable.hpp
+sharkCompiler.cpp                       llvmHeaders.hpp
+sharkCompiler.cpp                       oopMap.hpp
+sharkCompiler.cpp                       oopRecorder.hpp
+sharkCompiler.cpp                       shark_globals.hpp
+sharkCompiler.cpp                       sharkBuilder.hpp
+sharkCompiler.cpp                       sharkCodeBuffer.hpp
+sharkCompiler.cpp                       sharkCompiler.hpp
+sharkCompiler.cpp                       sharkContext.hpp
+sharkCompiler.cpp                       sharkEntry.hpp
+sharkCompiler.cpp                       sharkFunction.hpp
+sharkCompiler.cpp                       sharkMemoryManager.hpp
+sharkCompiler.cpp                       sharkNativeWrapper.hpp
+
+sharkCompiler.hpp                       abstractCompiler.hpp
+sharkCompiler.hpp                       ciEnv.hpp
+sharkCompiler.hpp                       ciMethod.hpp
+sharkCompiler.hpp                       compileBroker.hpp
+sharkCompiler.hpp                       llvmHeaders.hpp
+sharkCompiler.hpp                       sharkMemoryManager.hpp
+
+sharkContext.cpp                        arrayOop.hpp
+sharkContext.cpp                        globalDefinitions.hpp
+sharkContext.cpp                        llvmHeaders.hpp
+sharkContext.cpp                        oop.hpp
+sharkContext.cpp                        sharkContext.hpp
+
+sharkContext.hpp                        llvmHeaders.hpp
+sharkContext.hpp                        sharkCompiler.hpp
+
+sharkConstant.cpp                       ciInstance.hpp
+sharkConstant.cpp                       ciStreams.hpp
+sharkConstant.cpp                       sharkBuilder.hpp
+sharkConstant.cpp                       sharkConstant.hpp
+sharkConstant.cpp                       sharkValue.hpp
+
+sharkConstant.hpp                       allocation.hpp
+sharkConstant.hpp                       ciStreams.hpp
+sharkConstant.hpp                       sharkBuilder.hpp
+sharkConstant.hpp                       sharkValue.hpp
+
+sharkEntry.hpp                          llvmHeaders.hpp
+
+sharkFunction.cpp                       allocation.hpp
+sharkFunction.cpp                       ciTypeFlow.hpp
+sharkFunction.cpp                       debug.hpp
+sharkFunction.cpp                       llvmHeaders.hpp
+sharkFunction.cpp                       llvmValue.hpp
+sharkFunction.cpp                       shark_globals.hpp
+sharkFunction.cpp                       sharkBuilder.hpp
+sharkFunction.cpp                       sharkEntry.hpp
+sharkFunction.cpp                       sharkFunction.hpp
+sharkFunction.cpp                       sharkState.hpp
+sharkFunction.cpp                       sharkTopLevelBlock.hpp
+
+sharkFunction.hpp                       allocation.hpp
+sharkFunction.hpp                       ciEnv.hpp
+sharkFunction.hpp                       ciStreams.hpp
+sharkFunction.hpp                       ciTypeFlow.hpp
+sharkFunction.hpp                       llvmHeaders.hpp
+sharkFunction.hpp                       llvmValue.hpp
+sharkFunction.hpp                       sharkBuilder.hpp
+sharkFunction.hpp                       sharkContext.hpp
+sharkFunction.hpp                       sharkInvariants.hpp
+sharkFunction.hpp                       sharkStack.hpp
+
+sharkInliner.cpp                        allocation.hpp
+sharkInliner.cpp                        bytecodes.hpp
+sharkInliner.cpp                        ciField.hpp
+sharkInliner.cpp                        ciMethod.hpp
+sharkInliner.cpp                        ciStreams.hpp
+sharkInliner.cpp                        shark_globals.hpp
+sharkInliner.cpp                        sharkBlock.hpp
+sharkInliner.cpp                        sharkConstant.hpp
+sharkInliner.cpp                        sharkInliner.hpp
+sharkInliner.cpp                        sharkIntrinsics.hpp
+sharkInliner.cpp                        sharkState.hpp
+sharkInliner.cpp                        sharkValue.hpp
+
+sharkInliner.hpp                        allocation.hpp
+sharkInliner.hpp                        ciMethod.hpp
+sharkInliner.hpp                        llvmHeaders.hpp
+sharkInliner.hpp                        sharkState.hpp
+
+sharkIntrinsics.cpp                     ciMethod.hpp
+sharkIntrinsics.cpp                     llvmHeaders.hpp
+sharkIntrinsics.cpp                     shark_globals.hpp
+sharkIntrinsics.cpp                     sharkIntrinsics.hpp
+sharkIntrinsics.cpp                     sharkState.hpp
+sharkIntrinsics.cpp                     sharkValue.hpp
+
+sharkIntrinsics.hpp                     allocation.hpp
+sharkIntrinsics.hpp                     ciMethod.hpp
+sharkIntrinsics.hpp                     llvmHeaders.hpp
+sharkIntrinsics.hpp                     sharkState.hpp
+
+sharkInvariants.cpp                     sharkInvariants.hpp
+
+sharkInvariants.hpp                     allocation.hpp
+sharkInvariants.hpp                     ciEnv.hpp
+sharkInvariants.hpp                     ciMethod.hpp
+sharkInvariants.hpp                     ciInstanceKlass.hpp
+sharkInvariants.hpp                     ciTypeFlow.hpp
+sharkInvariants.hpp                     debugInfoRec.hpp
+sharkInvariants.hpp                     dependencies.hpp
+sharkInvariants.hpp                     llvmHeaders.hpp
+sharkInvariants.hpp                     sharkBuilder.hpp
+
+sharkMemoryManager.hpp                  llvmHeaders.hpp
+sharkMemoryManager.hpp                  sharkEntry.hpp
+
+sharkMemoryManager.cpp                  llvmHeaders.hpp
+sharkMemoryManager.cpp                  sharkEntry.hpp
+sharkMemoryManager.cpp                  sharkMemoryManager.hpp
+
+sharkNativeWrapper.cpp                  llvmHeaders.hpp
+sharkNativeWrapper.cpp                  sharkNativeWrapper.hpp
+sharkNativeWrapper.cpp                  sharkType.hpp
+
+sharkNativeWrapper.hpp                  handles.hpp
+sharkNativeWrapper.hpp                  llvmHeaders.hpp
+sharkNativeWrapper.hpp                  sharkBuilder.hpp
+sharkNativeWrapper.hpp                  sharkContext.hpp
+sharkNativeWrapper.hpp                  sharkInvariants.hpp
+sharkNativeWrapper.hpp                  sharkStack.hpp
+
+sharkRuntime.cpp                        biasedLocking.hpp
+sharkRuntime.cpp                        deoptimization.hpp
+sharkRuntime.cpp                        llvmHeaders.hpp
+sharkRuntime.cpp                        klassOop.hpp
+sharkRuntime.cpp                        sharkRuntime.hpp
+sharkRuntime.cpp                        stack_<arch>.inline.hpp
+sharkRuntime.cpp                        thread.hpp
+
+sharkRuntime.hpp                        allocation.hpp
+sharkRuntime.hpp                        llvmHeaders.hpp
+sharkRuntime.hpp                        llvmValue.hpp
+sharkRuntime.hpp                        klassOop.hpp
+sharkRuntime.hpp                        thread.hpp
+
+sharkStack.cpp                          llvmHeaders.hpp
+sharkStack.cpp                          sharkFunction.hpp
+sharkStack.cpp                          sharkNativeWrapper.hpp
+sharkStack.cpp                          sharkStack.hpp
+sharkStack.cpp                          sharkType.hpp
+
+sharkStack.hpp                          llvmHeaders.hpp
+sharkStack.hpp                          sharkInvariants.hpp
+sharkStack.hpp                          sharkType.hpp
+
+sharkState.cpp                          allocation.hpp
+sharkState.cpp                          ciType.hpp
+sharkState.cpp                          ciTypeFlow.hpp
+sharkState.cpp                          sharkBuilder.hpp
+sharkState.cpp                          sharkCacheDecache.hpp
+sharkState.cpp                          sharkState.hpp
+sharkState.cpp                          sharkTopLevelBlock.hpp
+sharkState.cpp                          sharkType.hpp
+sharkState.cpp                          sharkValue.hpp
+
+sharkState.hpp                          allocation.hpp
+sharkState.hpp                          ciMethod.hpp
+sharkState.hpp                          llvmHeaders.hpp
+sharkState.hpp                          sharkBuilder.hpp
+sharkState.hpp                          sharkInvariants.hpp
+sharkState.hpp                          sharkValue.hpp
+
+sharkStateScanner.cpp                   sharkState.hpp
+sharkStateScanner.cpp                   sharkStateScanner.hpp
+
+sharkStateScanner.hpp                   allocation.hpp
+sharkStateScanner.hpp                   llvmHeaders.hpp
+sharkStateScanner.hpp                   sharkFunction.hpp
+sharkStateScanner.hpp                   sharkInvariants.hpp
+
+sharkTopLevelBlock.cpp                  allocation.hpp
+sharkTopLevelBlock.cpp                  bytecodes.hpp
+sharkTopLevelBlock.cpp                  ciField.hpp
+sharkTopLevelBlock.cpp                  ciInstance.hpp
+sharkTopLevelBlock.cpp                  ciObjArrayKlass.hpp
+sharkTopLevelBlock.cpp                  ciStreams.hpp
+sharkTopLevelBlock.cpp                  ciType.hpp
+sharkTopLevelBlock.cpp                  ciTypeFlow.hpp
+sharkTopLevelBlock.cpp                  debug.hpp
+sharkTopLevelBlock.cpp                  deoptimization.hpp
+sharkTopLevelBlock.cpp                  llvmHeaders.hpp
+sharkTopLevelBlock.cpp                  llvmValue.hpp
+sharkTopLevelBlock.cpp                  shark_globals.hpp
+sharkTopLevelBlock.cpp                  sharkCacheDecache.hpp
+sharkTopLevelBlock.cpp                  sharkTopLevelBlock.hpp
+sharkTopLevelBlock.cpp                  sharkBuilder.hpp
+sharkTopLevelBlock.cpp                  sharkConstant.hpp
+sharkTopLevelBlock.cpp                  sharkInliner.hpp
+sharkTopLevelBlock.cpp                  sharkState.hpp
+sharkTopLevelBlock.cpp                  sharkValue.hpp
+
+sharkTopLevelBlock.hpp                  allocation.hpp
+sharkTopLevelBlock.hpp                  bytecodes.hpp
+sharkTopLevelBlock.hpp                  ciStreams.hpp
+sharkTopLevelBlock.hpp                  ciType.hpp
+sharkTopLevelBlock.hpp                  ciTypeFlow.hpp
+sharkTopLevelBlock.hpp                  llvmHeaders.hpp
+sharkTopLevelBlock.hpp                  sharkBlock.hpp
+sharkTopLevelBlock.hpp                  sharkBuilder.hpp
+sharkTopLevelBlock.hpp                  sharkFunction.hpp
+sharkTopLevelBlock.hpp                  sharkState.hpp
+sharkTopLevelBlock.hpp                  sharkValue.hpp
+
+sharkType.hpp                           allocation.hpp
+sharkType.hpp                           ciType.hpp
+sharkType.hpp                           globalDefinitions.hpp
+sharkType.hpp                           llvmHeaders.hpp
+sharkType.hpp                           sharkContext.hpp
+
+sharkValue.cpp                          ciType.hpp
+sharkValue.cpp                          llvmHeaders.hpp
+sharkValue.cpp                          llvmValue.hpp
+sharkValue.cpp                          sharkBuilder.hpp
+sharkValue.cpp                          sharkValue.hpp
+
+sharkValue.hpp                          allocation.hpp
+sharkValue.hpp                          ciType.hpp
+sharkValue.hpp                          llvmHeaders.hpp
+sharkValue.hpp                          llvmValue.hpp
+sharkValue.hpp                          sharkType.hpp
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -339,7 +339,8 @@
 #define CHECK_NULL(obj_)                                                 \
     if ((obj_) == NULL) {                                                \
         VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), "");  \
-    }
+    }                                                                    \
+    VERIFY_OOP(obj_)
 
 #define VMdoubleConstZero() 0.0
 #define VMdoubleConstOne() 1.0
@@ -509,7 +510,7 @@
 
 /* 0xB0 */ &&opc_areturn,     &&opc_return,         &&opc_getstatic,    &&opc_putstatic,
 /* 0xB4 */ &&opc_getfield,    &&opc_putfield,       &&opc_invokevirtual,&&opc_invokespecial,
-/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,NULL,               &&opc_new,
+/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,&&opc_default,      &&opc_new,
 /* 0xBC */ &&opc_newarray,    &&opc_anewarray,      &&opc_arraylength,  &&opc_athrow,
 
 /* 0xC0 */ &&opc_checkcast,   &&opc_instanceof,     &&opc_monitorenter, &&opc_monitorexit,
@@ -539,6 +540,7 @@
   // this will trigger a VERIFY_OOP on entry
   if (istate->msg() != initialize && ! METHOD->is_static()) {
     oop rcvr = LOCALS_OBJECT(0);
+    VERIFY_OOP(rcvr);
   }
 #endif
 // #define HACK
@@ -547,7 +549,7 @@
 #endif // HACK
 
   /* QQQ this should be a stack method so we don't know actual direction */
-  assert(istate->msg() == initialize ||
+  guarantee(istate->msg() == initialize ||
          topOfStack >= istate->stack_limit() &&
          topOfStack < istate->stack_base(),
          "Stack top out of range");
@@ -613,6 +615,7 @@
             rcvr = METHOD->constants()->pool_holder()->klass_part()->java_mirror();
           } else {
             rcvr = LOCALS_OBJECT(0);
+            VERIFY_OOP(rcvr);
           }
           // The initial monitor is ours for the taking
           BasicObjectLock* mon = &istate->monitor_base()[-1];
@@ -735,6 +738,7 @@
     case popping_frame: {
       // returned from a java call to pop the frame, restart the call
       // clear the message so we don't confuse ourselves later
+      ShouldNotReachHere();  // we don't return this.
       assert(THREAD->pop_frame_in_process(), "wrong frame pop state");
       istate->set_msg(no_request);
       THREAD->clr_pop_frame_in_process();
@@ -801,6 +805,7 @@
       // continue locking now that we have a monitor to use
       // we expect to find newly allocated monitor at the "top" of the monitor stack.
       oop lockee = STACK_OBJECT(-1);
+      VERIFY_OOP(lockee);
       // derefing's lockee ought to provoke implicit null check
       // find a free monitor
       BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base();
@@ -911,6 +916,7 @@
           /* load from local variable */
 
       CASE(_aload):
+          VERIFY_OOP(LOCALS_OBJECT(pc[1]));
           SET_STACK_OBJECT(LOCALS_OBJECT(pc[1]), 0);
           UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
 
@@ -930,6 +936,7 @@
 #undef  OPC_LOAD_n
 #define OPC_LOAD_n(num)                                                 \
       CASE(_aload_##num):                                               \
+          VERIFY_OOP(LOCALS_OBJECT(num));                               \
           SET_STACK_OBJECT(LOCALS_OBJECT(num), 0);                      \
           UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);                         \
                                                                         \
@@ -975,6 +982,7 @@
           opcode = pc[1];
           switch(opcode) {
               case Bytecodes::_aload:
+                  VERIFY_OOP(LOCALS_OBJECT(reg));
                   SET_STACK_OBJECT(LOCALS_OBJECT(reg), 0);
                   UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1);
 
@@ -1099,7 +1107,7 @@
       CASE(_i##opcname):                                                \
           if (test && (STACK_INT(-1) == 0)) {                           \
               VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
-                            "/ by int zero");                           \
+                            "/ by zero");                               \
           }                                                             \
           SET_STACK_INT(VMint##opname(STACK_INT(-2),                    \
                                       STACK_INT(-1)),                   \
@@ -1277,7 +1285,12 @@
           jfloat f;
           jdouble r;
           f = STACK_FLOAT(-1);
+#ifdef IA64
+          // IA64 gcc bug
+          r = ( f == 0.0f ) ? (jdouble) f : (jdouble) f + ia64_double_zero;
+#else
           r = (jdouble) f;
+#endif
           MORE_STACK(-1); // POP
           SET_STACK_DOUBLE(r, 1);
           UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
@@ -1471,6 +1484,7 @@
       CASE(_return_register_finalizer): {
 
           oop rcvr = LOCALS_OBJECT(0);
+          VERIFY_OOP(rcvr);
           if (rcvr->klass()->klass_part()->has_finalizer()) {
             CALL_VM(InterpreterRuntime::register_finalizer(THREAD, rcvr), handle_exception);
           }
@@ -1561,6 +1575,7 @@
        */
       CASE(_aastore): {
           oop rhsObject = STACK_OBJECT(-1);
+          VERIFY_OOP(rhsObject);
           ARRAY_INTRO( -3);
           // arrObj, index are set
           if (rhsObject != NULL) {
@@ -1703,6 +1718,7 @@
                 obj = (oop)NULL;
               } else {
                 obj = (oop) STACK_OBJECT(-1);
+                VERIFY_OOP(obj);
               }
               CALL_VM(InterpreterRuntime::post_field_access(THREAD,
                                           obj,
@@ -1728,6 +1744,7 @@
           int field_offset = cache->f2();
           if (cache->is_volatile()) {
             if (tos_type == atos) {
+              VERIFY_OOP(obj->obj_field_acquire(field_offset));
               SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1);
             } else if (tos_type == itos) {
               SET_STACK_INT(obj->int_field_acquire(field_offset), -1);
@@ -1748,6 +1765,7 @@
             }
           } else {
             if (tos_type == atos) {
+              VERIFY_OOP(obj->obj_field(field_offset));
               SET_STACK_OBJECT(obj->obj_field(field_offset), -1);
             } else if (tos_type == itos) {
               SET_STACK_INT(obj->int_field(field_offset), -1);
@@ -1799,6 +1817,7 @@
                 } else {
                   obj = (oop) STACK_OBJECT(-2);
                 }
+                VERIFY_OOP(obj);
               }
 
               CALL_VM(InterpreterRuntime::post_field_modification(THREAD,
@@ -1837,6 +1856,7 @@
             if (tos_type == itos) {
               obj->release_int_field_put(field_offset, STACK_INT(-1));
             } else if (tos_type == atos) {
+              VERIFY_OOP(STACK_OBJECT(-1));
               obj->release_obj_field_put(field_offset, STACK_OBJECT(-1));
               OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0);
             } else if (tos_type == btos) {
@@ -1857,6 +1877,7 @@
             if (tos_type == itos) {
               obj->int_field_put(field_offset, STACK_INT(-1));
             } else if (tos_type == atos) {
+              VERIFY_OOP(STACK_OBJECT(-1));
               obj->obj_field_put(field_offset, STACK_OBJECT(-1));
               OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0);
             } else if (tos_type == btos) {
@@ -1961,6 +1982,7 @@
       }
       CASE(_checkcast):
           if (STACK_OBJECT(-1) != NULL) {
+            VERIFY_OOP(STACK_OBJECT(-1));
             u2 index = Bytes::get_Java_u2(pc+1);
             if (ProfileInterpreter) {
               // needs Profile_checkcast QQQ
@@ -1999,6 +2021,7 @@
           if (STACK_OBJECT(-1) == NULL) {
             SET_STACK_INT(0, -1);
           } else {
+            VERIFY_OOP(STACK_OBJECT(-1));
             u2 index = Bytes::get_Java_u2(pc+1);
             // Constant pool may have actual klass or unresolved klass. If it is
             // unresolved we must resolve it
@@ -2044,10 +2067,12 @@
             break;
 
           case JVM_CONSTANT_String:
+            VERIFY_OOP(constants->resolved_string_at(index));
             SET_STACK_OBJECT(constants->resolved_string_at(index), 0);
             break;
 
           case JVM_CONSTANT_Class:
+            VERIFY_OOP(constants->resolved_klass_at(index)->klass_part()->java_mirror());
             SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0);
             break;
 
@@ -2059,17 +2084,6 @@
             THREAD->set_vm_result(NULL);
             break;
 
-#if 0
-          CASE(_fast_igetfield):
-          CASE(_fastagetfield):
-          CASE(_fast_aload_0):
-          CASE(_fast_iaccess_0):
-          CASE(__fast_aaccess_0):
-          CASE(_fast_linearswitch):
-          CASE(_fast_binaryswitch):
-            fatal("unsupported fast bytecode");
-#endif
-
           default:  ShouldNotReachHere();
           }
           UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1);
@@ -2122,6 +2136,7 @@
             // get receiver
             int parms = cache->parameter_size();
             // Same comments as invokevirtual apply here
+            VERIFY_OOP(STACK_OBJECT(-parms));
             instanceKlass* rcvrKlass = (instanceKlass*)
                                  STACK_OBJECT(-parms)->klass()->klass_part();
             callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()];
@@ -2205,6 +2220,7 @@
               // this fails with an assert
               // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass());
               // but this works
+              VERIFY_OOP(STACK_OBJECT(-parms));
               instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part();
               /*
                 Executing this code in java.lang.String:
@@ -2651,14 +2667,14 @@
                                 LOCALS_SLOT(METHOD->size_of_parameters() - 1));
         THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit);
       }
-      UPDATE_PC_AND_RETURN(1);
-    } else {
-      // Normal return
-      // Advance the pc and return to frame manager
-      istate->set_msg(return_from_method);
-      istate->set_return_kind((Bytecodes::Code)opcode);
-      UPDATE_PC_AND_RETURN(1);
+      THREAD->clr_pop_frame_in_process();
     }
+
+    // Normal return
+    // Advance the pc and return to frame manager
+    istate->set_msg(return_from_method);
+    istate->set_return_kind((Bytecodes::Code)opcode);
+    UPDATE_PC_AND_RETURN(1);
   } /* handle_return: */
 
 // This is really a fatal error return
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -440,7 +440,7 @@
  * iushr, ishl, and ishr bytecodes, respectively.
  */
 
-static jint VMintUshr(jint op, jint num);
+static juint VMintUshr(jint op, jint num);
 static jint VMintShl (jint op, jint num);
 static jint VMintShr (jint op, jint num);
 
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -27,14 +27,11 @@
 #ifdef CC_INTERP
 
 #ifdef ASSERT
-extern "C" { typedef void (*verify_oop_fn_t)(oop, const char *);};
-#define VERIFY_OOP(o) \
-        /*{ verify_oop_fn_t verify_oop_entry = \
-            *StubRoutines::verify_oop_subroutine_entry_address(); \
-          if (verify_oop_entry) { \
-             (*verify_oop_entry)((o), "Not an oop!"); \
-          } \
-        }*/
+#define VERIFY_OOP(o_) \
+      if (VerifyOops) { \
+        assert((oop(o_))->is_oop_or_null(), "Not an oop!"); \
+        StubRoutines::_verify_oop_count++;  \
+      }
 #else
 #define VERIFY_OOP(o)
 #endif
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -41,20 +41,20 @@
 }
 
 
-void InterpreterCodelet::print() {
+void InterpreterCodelet::print_on(outputStream* st) const {
   if (PrintInterpreter) {
-    tty->cr();
-    tty->print_cr("----------------------------------------------------------------------");
+    st->cr();
+    st->print_cr("----------------------------------------------------------------------");
   }
 
-  if (description() != NULL) tty->print("%s  ", description());
-  if (bytecode()    >= 0   ) tty->print("%d %s  ", bytecode(), Bytecodes::name(bytecode()));
-  tty->print_cr("[" INTPTR_FORMAT ", " INTPTR_FORMAT "]  %d bytes",
+  if (description() != NULL) st->print("%s  ", description());
+  if (bytecode()    >= 0   ) st->print("%d %s  ", bytecode(), Bytecodes::name(bytecode()));
+  st->print_cr("[" INTPTR_FORMAT ", " INTPTR_FORMAT "]  %d bytes",
                 code_begin(), code_end(), code_size());
 
   if (PrintInterpreter) {
-    tty->cr();
-    Disassembler::decode(code_begin(), code_end(), tty);
+    st->cr();
+    Disassembler::decode(code_begin(), code_end(), st);
   }
 }
 
--- a/hotspot/src/share/vm/interpreter/interpreter.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/interpreter/interpreter.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -52,7 +52,8 @@
 
   // Debugging
   void    verify();
-  void    print();
+  void    print_on(outputStream* st) const;
+  void    print() const { print_on(tty); }
 
   // Interpreter-specific initialization
   void    initialize(const char* description, Bytecodes::Code bytecode);
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -281,9 +281,7 @@
  public:
   void pass_int()                                { /* ignore */ }
   void pass_long()                               { /* ignore */ }
-#if defined(_LP64) || defined(ZERO)
   void pass_float()                              { /* ignore */ }
-#endif
   void pass_double()                             { /* ignore */ }
   void pass_object()                             { set_one(offset()); }
 
--- a/hotspot/src/share/vm/memory/allocation.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/memory/allocation.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -43,24 +43,73 @@
   switch (type) {
    case C_HEAP:
     res = (address)AllocateHeap(size, "C_Heap: ResourceOBJ");
+    DEBUG_ONLY(set_allocation_type(res, C_HEAP);)
     break;
    case RESOURCE_AREA:
+    // new(size) sets allocation type RESOURCE_AREA.
     res = (address)operator new(size);
     break;
    default:
     ShouldNotReachHere();
   }
-  // Set allocation type in the resource object for assertion checks.
-  DEBUG_ONLY(((ResourceObj *)res)->_allocation = type;)
   return res;
 }
 
 void ResourceObj::operator delete(void* p) {
   assert(((ResourceObj *)p)->allocated_on_C_heap(),
          "delete only allowed for C_HEAP objects");
+  DEBUG_ONLY(((ResourceObj *)p)->_allocation = badHeapOopVal;)
   FreeHeap(p);
 }
 
+#ifdef ASSERT
+void ResourceObj::set_allocation_type(address res, allocation_type type) {
+    // Set allocation type in the resource object
+    uintptr_t allocation = (uintptr_t)res;
+    assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least");
+    assert(type <= allocation_mask, "incorrect allocation type");
+    ((ResourceObj *)res)->_allocation = ~(allocation + type);
+}
+
+ResourceObj::allocation_type ResourceObj::get_allocation_type() const {
+    assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object");
+    return (allocation_type)((~_allocation) & allocation_mask);
+}
+
+ResourceObj::ResourceObj() { // default constructor
+    if (~(_allocation | allocation_mask) != (uintptr_t)this) {
+      set_allocation_type((address)this, STACK_OR_EMBEDDED);
+    } else if (allocated_on_stack()) {
+      // For some reason we got a value which looks like an allocation on stack.
+      // Pass if it is really allocated on stack.
+      assert(Thread::current()->on_local_stack((address)this),"should be on stack");
+    } else {
+      assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(),
+             "allocation_type should be set by operator new()");
+    }
+}
+
+ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor
+    // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream.
+    set_allocation_type((address)this, STACK_OR_EMBEDDED);
+}
+
+ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment
+    // Used in InlineTree::ok_to_inline() for WarmCallInfo.
+    assert(allocated_on_stack(), "copy only into local");
+    // Keep current _allocation value;
+    return *this;
+}
+
+ResourceObj::~ResourceObj() {
+    // allocated_on_C_heap() also checks that encoded (in _allocation) address == this.
+    if (!allocated_on_C_heap()) {  // ResourceObj::delete() zaps _allocation for C_heap.
+      _allocation = badHeapOopVal; // zap type
+    }
+}
+#endif // ASSERT
+
+
 void trace_heap_malloc(size_t size, const char* name, void* p) {
   // A lock is not needed here - tty uses a lock internally
   tty->print_cr("Heap malloc " INTPTR_FORMAT " %7d %s", p, size, name == NULL ? "" : name);
@@ -166,32 +215,40 @@
     _medium_pool = new ChunkPool(Chunk::medium_size + Chunk::aligned_overhead_size());
     _small_pool  = new ChunkPool(Chunk::init_size   + Chunk::aligned_overhead_size());
   }
+
+  static void clean() {
+    enum { BlocksToKeep = 5 };
+     _small_pool->free_all_but(BlocksToKeep);
+     _medium_pool->free_all_but(BlocksToKeep);
+     _large_pool->free_all_but(BlocksToKeep);
+  }
 };
 
 ChunkPool* ChunkPool::_large_pool  = NULL;
 ChunkPool* ChunkPool::_medium_pool = NULL;
 ChunkPool* ChunkPool::_small_pool  = NULL;
 
-
 void chunkpool_init() {
   ChunkPool::initialize();
 }
 
+void
+Chunk::clean_chunk_pool() {
+  ChunkPool::clean();
+}
+
 
 //--------------------------------------------------------------------------------------
 // ChunkPoolCleaner implementation
+//
 
 class ChunkPoolCleaner : public PeriodicTask {
-  enum { CleaningInterval = 5000,        // cleaning interval in ms
-         BlocksToKeep     = 5            // # of extra blocks to keep
-  };
+  enum { CleaningInterval = 5000 };      // cleaning interval in ms
 
  public:
    ChunkPoolCleaner() : PeriodicTask(CleaningInterval) {}
    void task() {
-     ChunkPool::small_pool()->free_all_but(BlocksToKeep);
-     ChunkPool::medium_pool()->free_all_but(BlocksToKeep);
-     ChunkPool::large_pool()->free_all_but(BlocksToKeep);
+     ChunkPool::clean();
    }
 };
 
--- a/hotspot/src/share/vm/memory/allocation.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/memory/allocation.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -174,9 +174,10 @@
 
   // Start the chunk_pool cleaner task
   static void start_chunk_pool_cleaner_task();
+
+  static void clean_chunk_pool();
 };
 
-
 //------------------------------Arena------------------------------------------
 // Fast allocation of memory
 class Arena: public CHeapObj {
@@ -316,32 +317,36 @@
 // use delete to deallocate.
 class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
  public:
-  enum allocation_type { UNKNOWN = 0, C_HEAP, RESOURCE_AREA, ARENA };
+  enum allocation_type { STACK_OR_EMBEDDED = 0, RESOURCE_AREA, C_HEAP, ARENA, allocation_mask = 0x3 };
+  static void set_allocation_type(address res, allocation_type type) NOT_DEBUG_RETURN;
 #ifdef ASSERT
  private:
-  allocation_type _allocation;
+  // When this object is allocated on stack the new() operator is not
+  // called but garbage on stack may look like a valid allocation_type.
+  // Store negated 'this' pointer when new() is called to distinguish cases.
+  uintptr_t _allocation;
  public:
-  bool allocated_on_C_heap()    { return _allocation == C_HEAP; }
+  allocation_type get_allocation_type() const;
+  bool allocated_on_stack()    const { return get_allocation_type() == STACK_OR_EMBEDDED; }
+  bool allocated_on_res_area() const { return get_allocation_type() == RESOURCE_AREA; }
+  bool allocated_on_C_heap()   const { return get_allocation_type() == C_HEAP; }
+  bool allocated_on_arena()    const { return get_allocation_type() == ARENA; }
+  ResourceObj(); // default construtor
+  ResourceObj(const ResourceObj& r); // default copy construtor
+  ResourceObj& operator=(const ResourceObj& r); // default copy assignment
+  ~ResourceObj();
 #endif // ASSERT
 
  public:
   void* operator new(size_t size, allocation_type type);
   void* operator new(size_t size, Arena *arena) {
       address res = (address)arena->Amalloc(size);
-      // Set allocation type in the resource object
-      DEBUG_ONLY(((ResourceObj *)res)->_allocation = ARENA;)
+      DEBUG_ONLY(set_allocation_type(res, ARENA);)
       return res;
   }
   void* operator new(size_t size) {
       address res = (address)resource_allocate_bytes(size);
-      // Set allocation type in the resource object
-      DEBUG_ONLY(((ResourceObj *)res)->_allocation = RESOURCE_AREA;)
-      return res;
-  }
-  void* operator new(size_t size, void* where, allocation_type type) {
-      void* res = where;
-      // Set allocation type in the resource object
-      DEBUG_ONLY(((ResourceObj *)res)->_allocation = type;)
+      DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
       return res;
   }
   void  operator delete(void* p);
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
   friend class VMStructs;
   friend class CardTableRS;
   friend class CheckForUnmarkedOops; // Needs access to raw card bytes.
+  friend class SharkBuilder;
 #ifndef PRODUCT
   // For debugging.
   friend class GuaranteeNotModClosure;
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -941,7 +941,9 @@
             VerifyBeforeExit ||
             PrintAssembly    ||
             tty->count() != 0 ||   // already printing
-            VerifyAfterGC, "too expensive");
+            VerifyAfterGC    ||
+    VMError::fatal_error_in_progress(), "too expensive");
+
   #endif
   // This might be sped up with a cache of the last generation that
   // answered yes.
--- a/hotspot/src/share/vm/memory/generation.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/memory/generation.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -131,7 +131,9 @@
   enum SomePublicConstants {
     // Generations are GenGrain-aligned and have size that are multiples of
     // GenGrain.
-    LogOfGenGrain = 16,
+    // Note: on ARM we add 1 bit for card_table_base to be properly aligned
+    // (we expect its low byte to be zero - see implementation of post_barrier)
+    LogOfGenGrain = 16 ARM_ONLY(+1),
     GenGrain = 1 << LogOfGenGrain
   };
 
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -179,8 +179,6 @@
   return JVMTI_CLASS_STATUS_ARRAY;
 }
 
-#ifndef PRODUCT
-
 // Printing
 
 void arrayKlass::oop_print_on(oop obj, outputStream* st) {
@@ -189,8 +187,6 @@
   st->print_cr(" - length: %d", arrayOop(obj)->length());
 }
 
-#endif
-
 // Verification
 
 void arrayKlass::oop_verify_on(oop obj, outputStream* st) {
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -115,20 +115,15 @@
   // Return a handle.
   static void     complete_create_array_klass(arrayKlassHandle k, KlassHandle super_klass, TRAPS);
 
- public:
-   // jvm support
-   jint compute_modifier_flags(TRAPS) const;
+  // jvm support
+  jint compute_modifier_flags(TRAPS) const;
 
- public:
-   // JVMTI support
-   jint jvmti_class_status() const;
+  // JVMTI support
+  jint jvmti_class_status() const;
 
-#ifndef PRODUCT
- public:
   // Printing
   void oop_print_on(oop obj, outputStream* st);
-#endif
- public:
+
   // Verification
   void oop_verify_on(oop obj, outputStream* st);
 };
--- a/hotspot/src/share/vm/oops/arrayKlassKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/arrayKlassKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -151,15 +151,12 @@
 }
 #endif // SERIALGC
 
-#ifndef PRODUCT
-
 // Printing
 
 void arrayKlassKlass::oop_print_on(oop obj, outputStream* st) {
   assert(obj->is_klass(), "must be klass");
   klassKlass::oop_print_on(obj, st);
 }
-#endif //PRODUCT
 
 void arrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) {
   assert(obj->is_klass(), "must be klass");
--- a/hotspot/src/share/vm/oops/arrayKlassKlass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/arrayKlassKlass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -55,12 +55,9 @@
   int oop_oop_iterate(oop obj, OopClosure* blk);
   int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr);
 
- public:
   // Printing
   void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
   void oop_print_on(oop obj, outputStream* st);
-#endif //PRODUCT
 
   // Verification
   const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -154,8 +154,6 @@
 }
 #endif // SERIALGC
 
-#ifndef PRODUCT
-
 // Printing
 
 void compiledICHolderKlass::oop_print_on(oop obj, outputStream* st) {
@@ -166,8 +164,6 @@
   st->print(" - klass:  "); c->holder_klass()->print_value_on(st); st->cr();
 }
 
-#endif //PRODUCT
-
 void compiledICHolderKlass::oop_print_value_on(oop obj, outputStream* st) {
   assert(obj->is_compiledICHolder(), "must be compiledICHolder");
   Klass::oop_print_value_on(obj, st);
--- a/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -68,12 +68,9 @@
   int  oop_oop_iterate(oop obj, OopClosure* blk);
   int  oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr);
 
- public:
   // Printing
   void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
   void oop_print_on      (oop obj, outputStream* st);
-#endif //PRODUCT
 
   // Verification
   const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/constMethodKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/constMethodKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -197,8 +197,6 @@
 }
 #endif // SERIALGC
 
-#ifndef PRODUCT
-
 // Printing
 
 void constMethodKlass::oop_print_on(oop obj, outputStream* st) {
@@ -216,8 +214,6 @@
   }
 }
 
-#endif //PRODUCT
-
 // Short version of printing constMethodOop - just print the name of the
 // method it belongs to.
 void constMethodKlass::oop_print_value_on(oop obj, outputStream* st) {
--- a/hotspot/src/share/vm/oops/constMethodKlass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/constMethodKlass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -77,12 +77,9 @@
   int oop_oop_iterate(oop obj, OopClosure* blk);
   int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr);
 
- public:
   // Printing
   void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
   void oop_print_on      (oop obj, outputStream* st);
-#endif //PRODUCT
 
   // Verify operations
   const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/constantPoolKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/constantPoolKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -299,8 +299,6 @@
 }
 #endif // SERIALGC
 
-#ifndef PRODUCT
-
 // Printing
 
 void constantPoolKlass::oop_print_on(oop obj, outputStream* st) {
@@ -392,8 +390,6 @@
   st->cr();
 }
 
-#endif
-
 void constantPoolKlass::oop_print_value_on(oop obj, outputStream* st) {
   assert(obj->is_constantPool(), "must be constantPool");
   constantPoolOop cp = constantPoolOop(obj);
--- a/hotspot/src/share/vm/oops/constantPoolKlass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/constantPoolKlass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -61,18 +61,13 @@
   int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr);
 
   // Allocation profiling support
-  // no idea why this is pure virtual and not in Klass ???
   juint alloc_size() const              { return _alloc_size; }
   void set_alloc_size(juint n)          { _alloc_size = n; }
 
- public:
   // Printing
   void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
   void oop_print_on(oop obj, outputStream* st);
-#endif
 
- public:
   // Verification
   const char* internal_name() const;
   void oop_verify_on(oop obj, outputStream* st);
--- a/hotspot/src/share/vm/oops/cpCacheKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/cpCacheKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -248,8 +248,6 @@
 }
 #endif // SERIALGC
 
-#ifndef PRODUCT
-
 void constantPoolCacheKlass::oop_print_on(oop obj, outputStream* st) {
   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
@@ -259,8 +257,6 @@
   for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->print(st, i);
 }
 
-#endif
-
 void constantPoolCacheKlass::oop_print_value_on(oop obj, outputStream* st) {
   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
--- a/hotspot/src/share/vm/oops/cpCacheKlass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/cpCacheKlass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -61,14 +61,10 @@
   juint alloc_size() const              { return _alloc_size; }
   void set_alloc_size(juint n)          { _alloc_size = n; }
 
- public:
   // Printing
   void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
   void oop_print_on(oop obj, outputStream* st);
-#endif
 
- public:
   // Verification
   const char* internal_name() const;
   void oop_verify_on(oop obj, outputStream* st);
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -2111,7 +2111,13 @@
   // We do not distinguish between different types of errors for verification
   // errors.  Let the verifier give a better message.
   const char *msg = "Illegal class file encountered. Try running with -Xverify:all";
-  error_work(msg, NULL);
+  _got_error = true;
+  // Append method name
+  char msg_buffer2[512];
+  jio_snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg,
+               method()->name()->as_C_string());
+  _exception = Exceptions::new_exception(Thread::current(),
+                vmSymbols::java_lang_LinkageError(), msg_buffer2);
 }
 
 //
--- a/hotspot/src/share/vm/oops/klass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/klass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -520,8 +520,6 @@
   return 0;
 }
 
-#ifndef PRODUCT
-
 // Printing
 
 void Klass::oop_print_on(oop obj, outputStream* st) {
@@ -541,8 +539,6 @@
   st->cr();
 }
 
-#endif //PRODUCT
-
 void Klass::oop_print_value_on(oop obj, outputStream* st) {
   // print title
   ResourceMark rm;              // Cannot print in debug mode without this
--- a/hotspot/src/share/vm/oops/klass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/klass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -772,16 +772,12 @@
   // jvm support
   virtual jint compute_modifier_flags(TRAPS) const;
 
- public:
   // JVMTI support
   virtual jint jvmti_class_status() const;
 
- public:
   // Printing
   virtual void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
   virtual void oop_print_on      (oop obj, outputStream* st);
-#endif //PRODUCT
 
   // Verification
   virtual const char* internal_name() const = 0;
--- a/hotspot/src/share/vm/oops/klassKlass.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/klassKlass.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -194,16 +194,12 @@
 #endif // SERIALGC
 
 
-#ifndef PRODUCT
-
 // Printing
 
 void klassKlass::oop_print_on(oop obj, outputStream* st) {
   Klass::oop_print_on(obj, st);
 }
 
-#endif //PRODUCT
-
 void klassKlass::oop_print_value_on(oop obj, outputStream* st) {
   Klass::oop_print_value_on(obj, st);
 }
--- a/hotspot/src/share/vm/oops/klassKlass.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/klassKlass.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -67,12 +67,9 @@
   juint alloc_size() const              { return _alloc_size; }
   void set_alloc_size(juint n)          { _alloc_size = n; }
 
- public:
   // Printing
   void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
   void oop_print_on      (oop obj, outputStream* st);
-#endif //PRODUCT
 
   // Verification
   const char* internal_name() const;
--- a/hotspot/src/share/vm/oops/methodOop.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/methodOop.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -751,10 +751,14 @@
   }
 
   OrderAccess::storestore();
+#ifdef SHARK
+  mh->_from_interpreted_entry = code->instructions_begin();
+#else
   mh->_from_compiled_entry = code->verified_entry_point();
   OrderAccess::storestore();
   // Instantly compiled code can execute.
   mh->_from_interpreted_entry = mh->get_i2c_entry();
+#endif // SHARK
 
 }
 
--- a/hotspot/src/share/vm/oops/oop.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/oops/oop.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -29,15 +29,6 @@
 
 BarrierSet* oopDesc::_bs = NULL;
 
-#ifdef PRODUCT
-void oopDesc::print_on(outputStream* st) const {}
-void oopDesc::print_address_on(outputStream* st) const {}
-char* oopDesc::print_string() { return NULL; }
-void oopDesc::print()         {}
-void oopDesc::print_address() {}
-
-#else //PRODUCT
-
 void oopDesc::print_on(outputStream* st) const {
   if (this == NULL) {
     st->print_cr("NULL");
@@ -62,10 +53,6 @@
   return st.as_string();
 }
 
-#endif // PRODUCT
-
-// The print_value functions are present in all builds, to support the disassembler.
-
 void oopDesc::print_value() {
   print_value_on(tty);
 }
@@ -83,9 +70,7 @@
     st->print("NULL");
   } else if (java_lang_String::is_instance(obj)) {
     java_lang_String::print(obj, st);
-#ifndef PRODUCT
     if (PrintOopAddress) print_address_on(st);
-#endif //PRODUCT
 #ifdef ASSERT
   } else if (!Universe::heap()->is_in(obj) || !Universe::heap()->is_in(klass())) {
     st->print("### BAD OOP %p ###", (address)obj);
--- a/hotspot/src/share/vm/opto/block.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/block.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -353,7 +353,8 @@
 PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) :
   Phase(CFG),
   _bbs(a),
-  _root(r)
+  _root(r),
+  _node_latency(NULL)
 #ifndef PRODUCT
   , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
 #endif
--- a/hotspot/src/share/vm/opto/block.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/block.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -374,7 +374,7 @@
   float _outer_loop_freq;       // Outmost loop frequency
 
   // Per node latency estimation, valid only during GCM
-  GrowableArray<uint> _node_latency;
+  GrowableArray<uint> *_node_latency;
 
 #ifndef PRODUCT
   bool _trace_opto_pipelining;  // tracing flag
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -281,6 +281,12 @@
   product(bool, InsertMemBarAfterArraycopy, true,                           \
           "Insert memory barrier after arraycopy call")                     \
                                                                             \
+  develop(bool, SubsumeLoads, true,                                         \
+          "Attempt to compile while subsuming loads into machine instructions.") \
+                                                                            \
+  develop(bool, StressRecompilation, false,                                 \
+          "Recompile each compiled method without subsuming loads or escape analysis.") \
+                                                                            \
   /* controls for tier 1 compilations */                                    \
                                                                             \
   develop(bool, Tier1CountInvocations, true,                                \
--- a/hotspot/src/share/vm/opto/c2compiler.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -103,13 +103,14 @@
   if (!is_initialized()) {
     initialize();
   }
-  bool subsume_loads = true;
+  bool subsume_loads = SubsumeLoads;
   bool do_escape_analysis = DoEscapeAnalysis &&
     !env->jvmti_can_access_local_variables();
   while (!env->failing()) {
     // Attempt to compile while subsuming loads into machine instructions.
     Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis);
 
+
     // Check result and retry if appropriate.
     if (C.failure_reason() != NULL) {
       if (C.failure_reason_is(retry_no_subsuming_loads())) {
@@ -127,6 +128,16 @@
       // on the ciEnv via env->record_method_not_compilable().
       env->record_failure(C.failure_reason());
     }
+    if (StressRecompilation) {
+      if (subsume_loads) {
+        subsume_loads = false;
+        continue;  // retry
+      }
+      if (do_escape_analysis) {
+        do_escape_analysis = false;
+        continue;  // retry
+      }
+    }
 
     // No retry; just break the loop.
     break;
--- a/hotspot/src/share/vm/opto/chaitin.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/chaitin.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -569,7 +569,7 @@
         if (trace_spilling() && lrg._def != NULL) {
           // collect defs for MultiDef printing
           if (lrg._defs == NULL) {
-            lrg._defs = new (_ifg->_arena) GrowableArray<Node*>();
+            lrg._defs = new (_ifg->_arena) GrowableArray<Node*>(_ifg->_arena, 2, 0, NULL);
             lrg._defs->append(lrg._def);
           }
           lrg._defs->append(n);
--- a/hotspot/src/share/vm/opto/compile.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/compile.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -904,8 +904,8 @@
   probe_alias_cache(NULL)->_index = AliasIdxTop;
 
   _intrinsics = NULL;
-  _macro_nodes = new GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
-  _predicate_opaqs = new GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
+  _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
+  _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
   register_library_intrinsics();
 }
 
--- a/hotspot/src/share/vm/opto/gcm.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -841,7 +841,7 @@
 #ifndef PRODUCT
   if (trace_opto_pipelining()) {
     tty->print("# latency_to_inputs: node_latency[%d] = %d for node",
-               n->_idx, _node_latency.at_grow(n->_idx));
+               n->_idx, _node_latency->at_grow(n->_idx));
     dump();
   }
 #endif
@@ -853,7 +853,7 @@
     return;
 
   uint nlen = n->len();
-  uint use_latency = _node_latency.at_grow(n->_idx);
+  uint use_latency = _node_latency->at_grow(n->_idx);
   uint use_pre_order = _bbs[n->_idx]->_pre_order;
 
   for ( uint j=0; j<nlen; j++ ) {
@@ -884,15 +884,15 @@
     uint delta_latency = n->latency(j);
     uint current_latency = delta_latency + use_latency;
 
-    if (_node_latency.at_grow(def->_idx) < current_latency) {
-      _node_latency.at_put_grow(def->_idx, current_latency);
+    if (_node_latency->at_grow(def->_idx) < current_latency) {
+      _node_latency->at_put_grow(def->_idx, current_latency);
     }
 
 #ifndef PRODUCT
     if (trace_opto_pipelining()) {
       tty->print_cr("#      %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d",
                     use_latency, j, delta_latency, current_latency, def->_idx,
-                    _node_latency.at_grow(def->_idx));
+                    _node_latency->at_grow(def->_idx));
     }
 #endif
   }
@@ -926,7 +926,7 @@
       return 0;
 
     uint nlen = use->len();
-    uint nl = _node_latency.at_grow(use->_idx);
+    uint nl = _node_latency->at_grow(use->_idx);
 
     for ( uint j=0; j<nlen; j++ ) {
       if (use->in(j) == n) {
@@ -962,7 +962,7 @@
 #ifndef PRODUCT
   if (trace_opto_pipelining()) {
     tty->print("# latency_from_outputs: node_latency[%d] = %d for node",
-               n->_idx, _node_latency.at_grow(n->_idx));
+               n->_idx, _node_latency->at_grow(n->_idx));
     dump();
   }
 #endif
@@ -975,7 +975,7 @@
     if (latency < l) latency = l;
   }
 
-  _node_latency.at_put_grow(n->_idx, latency);
+  _node_latency->at_put_grow(n->_idx, latency);
 }
 
 //------------------------------hoist_to_cheaper_block-------------------------
@@ -985,9 +985,9 @@
   const double delta = 1+PROB_UNLIKELY_MAG(4);
   Block* least       = LCA;
   double least_freq  = least->_freq;
-  uint target        = _node_latency.at_grow(self->_idx);
-  uint start_latency = _node_latency.at_grow(LCA->_nodes[0]->_idx);
-  uint end_latency   = _node_latency.at_grow(LCA->_nodes[LCA->end_idx()]->_idx);
+  uint target        = _node_latency->at_grow(self->_idx);
+  uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx);
+  uint end_latency   = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx);
   bool in_latency    = (target <= start_latency);
   const Block* root_block = _bbs[_root->_idx];
 
@@ -1005,7 +1005,7 @@
 #ifndef PRODUCT
   if (trace_opto_pipelining()) {
     tty->print("# Find cheaper block for latency %d: ",
-      _node_latency.at_grow(self->_idx));
+      _node_latency->at_grow(self->_idx));
     self->dump();
     tty->print_cr("#   B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
       LCA->_pre_order,
@@ -1032,9 +1032,9 @@
     if (mach && LCA == root_block)
       break;
 
-    uint start_lat = _node_latency.at_grow(LCA->_nodes[0]->_idx);
+    uint start_lat = _node_latency->at_grow(LCA->_nodes[0]->_idx);
     uint end_idx   = LCA->end_idx();
-    uint end_lat   = _node_latency.at_grow(LCA->_nodes[end_idx]->_idx);
+    uint end_lat   = _node_latency->at_grow(LCA->_nodes[end_idx]->_idx);
     double LCA_freq = LCA->_freq;
 #ifndef PRODUCT
     if (trace_opto_pipelining()) {
@@ -1073,7 +1073,7 @@
       tty->print_cr("#  Change latency for [%4d] from %d to %d", self->_idx, target, end_latency);
     }
 #endif
-    _node_latency.at_put_grow(self->_idx, end_latency);
+    _node_latency->at_put_grow(self->_idx, end_latency);
     partial_latency_of_defs(self);
   }
 
@@ -1255,8 +1255,7 @@
 
   // Compute the latency information (via backwards walk) for all the
   // instructions in the graph
-  GrowableArray<uint> node_latency;
-  _node_latency = node_latency;
+  _node_latency = new GrowableArray<uint>(); // resource_area allocation
 
   if( C->do_scheduling() )
     ComputeLatenciesBackwards(visited, stack);
@@ -1341,6 +1340,8 @@
     }
   }
 #endif
+  // Dead.
+  _node_latency = (GrowableArray<uint> *)0xdeadbeef;
 }
 
 
--- a/hotspot/src/share/vm/opto/lcm.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -113,7 +113,8 @@
     if( !m->is_Mach() ) continue;
     MachNode *mach = m->as_Mach();
     was_store = false;
-    switch( mach->ideal_Opcode() ) {
+    int iop = mach->ideal_Opcode();
+    switch( iop ) {
     case Op_LoadB:
     case Op_LoadUS:
     case Op_LoadD:
@@ -155,6 +156,12 @@
     default:                    // Also check for embedded loads
       if( !mach->needs_anti_dependence_check() )
         continue;               // Not an memory op; skip it
+      if( must_clone[iop] ) {
+        // Do not move nodes which produce flags because
+        // RA will try to clone it to place near branch and
+        // it will cause recompilation, see clone_node().
+        continue;
+      }
       {
         // Check that value is used in memory address in
         // instructions with embedded load (CmpP val1,(val2+off)).
@@ -461,7 +468,7 @@
       n_choice = 1;
     }
 
-    uint n_latency = cfg->_node_latency.at_grow(n->_idx);
+    uint n_latency = cfg->_node_latency->at_grow(n->_idx);
     uint n_score   = n->req();   // Many inputs get high score to break ties
 
     // Keep best latency found
@@ -738,7 +745,7 @@
         Node     *n = _nodes[j];
         int     idx = n->_idx;
         tty->print("#   ready cnt:%3d  ", ready_cnt[idx]);
-        tty->print("latency:%3d  ", cfg->_node_latency.at_grow(idx));
+        tty->print("latency:%3d  ", cfg->_node_latency->at_grow(idx));
         tty->print("%4d: %s\n", idx, n->Name());
       }
     }
@@ -765,7 +772,7 @@
 #ifndef PRODUCT
     if (cfg->trace_opto_pipelining()) {
       tty->print("#    select %d: %s", n->_idx, n->Name());
-      tty->print(", latency:%d", cfg->_node_latency.at_grow(n->_idx));
+      tty->print(", latency:%d", cfg->_node_latency->at_grow(n->_idx));
       n->dump();
       if (Verbose) {
         tty->print("#   ready list:");
@@ -957,6 +964,8 @@
     Block *sb = _succs[i];
     // Clone the entire area; ignoring the edge fixup for now.
     for( uint j = end; j > beg; j-- ) {
+      // It is safe here to clone a node with anti_dependence
+      // since clones dominate on each path.
       Node *clone = _nodes[j-1]->clone();
       sb->_nodes.insert( 1, clone );
       bbs.map(clone->_idx,sb);
--- a/hotspot/src/share/vm/opto/macro.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/macro.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -720,7 +720,7 @@
       if (basic_elem_type == T_OBJECT || basic_elem_type == T_ARRAY) {
         if (!elem_type->is_loaded()) {
           field_type = TypeInstPtr::BOTTOM;
-        } else if (field != NULL && field->is_constant()) {
+        } else if (field != NULL && field->is_constant() && field->is_static()) {
           // This can happen if the constant oop is non-perm.
           ciObject* con = field->constant_value().as_object();
           // Do not "join" in the previous type; it doesn't add value,
--- a/hotspot/src/share/vm/opto/output.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/output.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -382,6 +382,10 @@
           if (min_offset_from_last_call == 0) {
             blk_size += nop_size;
           }
+        } else if (mach->ideal_Opcode() == Op_Jump) {
+          const_size += b->_num_succs; // Address table size
+          // The size is valid even for 64 bit since it is
+          // multiplied by 2*jintSize on this method exit.
         }
       }
       min_offset_from_last_call += inst_size;
--- a/hotspot/src/share/vm/opto/reg_split.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/opto/reg_split.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -271,6 +271,32 @@
   return maxlrg;
 }
 
+//------------------------------clone_node----------------------------
+// Clone node with anti dependence check.
+Node* clone_node(Node* def, Block *b, Compile* C) {
+  if (def->needs_anti_dependence_check()) {
+#ifdef ASSERT
+    if (Verbose) {
+      tty->print_cr("RA attempts to clone node with anti_dependence:");
+      def->dump(-1); tty->cr();
+      tty->print_cr("into block:");
+      b->dump();
+    }
+#endif
+    if (C->subsume_loads() == true && !C->failing()) {
+      // Retry with subsume_loads == false
+      // If this is the first failure, the sentinel string will "stick"
+      // to the Compile object, and the C2Compiler will see it and retry.
+      C->record_failure(C2Compiler::retry_no_subsuming_loads());
+    } else {
+      // Bailout without retry
+      C->record_method_not_compilable("RA Split failed: attempt to clone node with anti_dependence");
+    }
+    return 0;
+  }
+  return def->clone();
+}
+
 //------------------------------split_Rematerialize----------------------------
 // Clone a local copy of the def.
 Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru ) {
@@ -298,8 +324,8 @@
     }
   }
 
-  Node *spill = def->clone();
-  if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) {
+  Node *spill = clone_node(def, b, C);
+  if (spill == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) {
     // Check when generating nodes
     return 0;
   }
@@ -834,13 +860,13 @@
               // The effect of this clone is to drop the node out of the block,
               // so that the allocator does not see it anymore, and therefore
               // does not attempt to assign it a register.
-              def = def->clone();
+              def = clone_node(def, b, C);
+              if (def == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) {
+                return 0;
+              }
               _names.extend(def->_idx,0);
               _cfg._bbs.map(def->_idx,b);
               n->set_req(inpidx, def);
-              if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) {
-                return 0;
-              }
               continue;
             }
 
--- a/hotspot/src/share/vm/prims/jni.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/prims/jni.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -3414,6 +3414,8 @@
 
   thread->initialize_tlab();
 
+  thread->cache_global_variables();
+
   // Crucial that we do not have a safepoint check for this thread, since it has
   // not been added to the Thread list yet.
   { Threads_lock->lock_without_safepoint_check();
--- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -24,6 +24,8 @@
 #ifndef _JAVA_JVMTIENVTHREADSTATE_H_
 #define _JAVA_JVMTIENVTHREADSTATE_H_
 
+class JvmtiEnv;
+
 ///////////////////////////////////////////////////////////////
 //
 // class JvmtiFramePop
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -2593,6 +2593,12 @@
       FLAG_IS_DEFAULT(UseVMInterruptibleIO)) {
     FLAG_SET_DEFAULT(UseVMInterruptibleIO, true);
   }
+#ifdef LINUX
+ if (JDK_Version::current().compare_major(6) <= 0 &&
+      FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
+    FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
+  }
+#endif // LINUX
   return JNI_OK;
 }
 
@@ -2659,6 +2665,28 @@
   }
 #endif
 
+  // If we are running in a headless jre, force java.awt.headless property
+  // to be true unless the property has already been set.
+  // Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state.
+  if (os::is_headless_jre()) {
+    const char* headless = Arguments::get_property("java.awt.headless");
+    if (headless == NULL) {
+      char envbuffer[128];
+      if (!os::getenv("JAVA_AWT_HEADLESS", envbuffer, sizeof(envbuffer))) {
+        if (!add_property("java.awt.headless=true")) {
+          return JNI_ENOMEM;
+        }
+      } else {
+        char buffer[256];
+        strcpy(buffer, "java.awt.headless=");
+        strcat(buffer, envbuffer);
+        if (!add_property(buffer)) {
+          return JNI_ENOMEM;
+        }
+      }
+    }
+  }
+
   if (!check_vm_args_consistency()) {
     return JNI_ERR;
   }
@@ -2979,6 +3007,14 @@
     CommandLineFlags::printFlags();
   }
 
+  // Apply CPU specific policy for the BiasedLocking
+  if (UseBiasedLocking) {
+    if (!VM_Version::use_biased_locking() &&
+        !(FLAG_IS_CMDLINE(UseBiasedLocking))) {
+      UseBiasedLocking = false;
+    }
+  }
+
   return JNI_OK;
 }
 
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -254,6 +254,7 @@
 
   }
 
+#ifndef SHARK
   // Compute the caller frame based on the sender sp of stub_frame and stored frame sizes info.
   CodeBlob* cb = stub_frame.cb();
   // Verify we have the right vframeArray
@@ -270,6 +271,10 @@
   assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking");
   Events::log("fetch unroll sp " INTPTR_FORMAT, unpack_sp);
 #endif
+#else
+  intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp();
+#endif // !SHARK
+
   // This is a guarantee instead of an assert because if vframe doesn't match
   // we will unpack the wrong deoptimized frame and wind up in strange places
   // where it will be very difficult to figure out what went wrong. Better
@@ -380,7 +385,9 @@
 
   frame_pcs[0] = deopt_sender.raw_pc();
 
+#ifndef SHARK
   assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc");
+#endif // SHARK
 
   UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
                                       caller_adjustment * BytesPerWord,
@@ -1073,7 +1080,7 @@
 JRT_END
 
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || defined(SHARK)
 void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
   // in case of an unresolved klass entry, load the class.
   if (constant_pool->tag_at(index).is_unresolved_klass()) {
@@ -1835,7 +1842,7 @@
     if (xtty != NULL)  xtty->tail("statistics");
   }
 }
-#else // COMPILER2
+#else // COMPILER2 || SHARK
 
 
 // Stubs for C1 only system.
@@ -1871,4 +1878,4 @@
   return buf;
 }
 
-#endif // COMPILER2
+#endif // COMPILER2 || SHARK
--- a/hotspot/src/share/vm/runtime/frame.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -876,6 +876,7 @@
 
 #endif /* CC_INTERP */
 
+#ifndef PPC
   if (m->is_native()) {
 #ifdef CC_INTERP
     f->do_oop((oop*)&istate->_oop_temp);
@@ -883,6 +884,11 @@
     f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset ));
 #endif /* CC_INTERP */
   }
+#else // PPC
+  if (m->is_native() && m->is_static()) {
+    f->do_oop(interpreter_frame_mirror_addr());
+  }
+#endif // PPC
 
   int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
 
@@ -1094,6 +1100,10 @@
     oops_entry_do(f, map);
   } else if (CodeCache::contains(pc())) {
     oops_code_blob_do(f, cf, map);
+#ifdef SHARK
+  } else if (is_fake_stub_frame()) {
+    // nothing to do
+#endif // SHARK
   } else {
     ShouldNotReachHere();
   }
--- a/hotspot/src/share/vm/runtime/frame.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -25,6 +25,7 @@
 typedef class BytecodeInterpreter* interpreterState;
 
 class CodeBlob;
+class vframeArray;
 
 
 // A frame represents a physical stack frame (an activation).  Frames
@@ -296,6 +297,9 @@
   void interpreter_frame_set_method(methodOop method);
   methodOop* interpreter_frame_method_addr() const;
   constantPoolCacheOop* interpreter_frame_cache_addr() const;
+#ifdef PPC
+  oop* interpreter_frame_mirror_addr() const;
+#endif
 
  public:
   // Entry frames
--- a/hotspot/src/share/vm/runtime/globals.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -181,6 +181,18 @@
   #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 notproduct}", DEFAULT },
 #endif
 
+#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark product}", DEFAULT },
+#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{Shark pd product}", DEFAULT },
+#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark diagnostic}", DEFAULT },
+#ifdef PRODUCT
+  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
+  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
+  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
+#else
+  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark}", DEFAULT },
+  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{Shark pd}", DEFAULT },
+  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark notproduct}", DEFAULT },
+#endif
 
 static Flag flagTable[] = {
  RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT)
@@ -194,6 +206,9 @@
 #ifdef COMPILER2
  C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
 #endif
+#ifdef SHARK
+ SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT)
+#endif
  {0, NULL, NULL}
 };
 
--- a/hotspot/src/share/vm/runtime/globals.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -22,7 +22,7 @@
  *
  */
 
-#if !defined(COMPILER1) && !defined(COMPILER2)
+#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)
 define_pd_global(bool, BackgroundCompilation,        false);
 define_pd_global(bool, UseTLAB,                      false);
 define_pd_global(bool, CICompileOSR,                 false);
@@ -607,7 +607,7 @@
   notproduct(bool, PrintMallocFree, false,                                  \
           "Trace calls to C heap malloc/free allocation")                   \
                                                                             \
-  notproduct(bool, PrintOopAddress, false,                                  \
+  product(bool, PrintOopAddress, false,                                     \
           "Always print the location of the oop")                           \
                                                                             \
   notproduct(bool, VerifyCodeCacheOften, false,                             \
@@ -2442,6 +2442,10 @@
           "Call fatal if this exception is thrown.  Example: "              \
           "java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \
                                                                             \
+  notproduct(ccstr, AbortVMOnExceptionMessage, NULL,                        \
+          "Call fatal if the exception pointed by AbortVMOnException "      \
+          "has this message.")                                              \
+                                                                            \
   develop(bool, DebugVtables, false,                                        \
           "add debugging code to vtable dispatch")                          \
                                                                             \
@@ -3554,7 +3558,6 @@
           "EINTR for I/O operations results in OS_INTRPT. The default value"\
           " of this flag is true for JDK 6 and earliers")
 
-
 /*
  *  Macros for factoring of globals
  */
--- a/hotspot/src/share/vm/runtime/java.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/java.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -378,7 +378,8 @@
   }
 
   // Terminate watcher thread - must before disenrolling any periodic task
-  WatcherThread::stop();
+  if (PeriodicTask::num_tasks() > 0)
+    WatcherThread::stop();
 
   // Print statistics gathered (profiling ...)
   if (Arguments::has_profile()) {
--- a/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -76,7 +76,6 @@
   JavaFrameAnchor()                              { clear(); }
   JavaFrameAnchor(JavaFrameAnchor *src)          { copy(src); }
 
-  address last_Java_pc(void)                     { return _last_Java_pc; }
   void set_last_Java_pc(address pc)              { _last_Java_pc = pc; }
 
   // Assembly stub generation helpers
--- a/hotspot/src/share/vm/runtime/os.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/os.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -735,6 +735,152 @@
   st->print_cr("elapsed time: %d seconds", (int)t);
 }
 
+// moved from debug.cpp (used to be find()) but still called from there
+// The print_pc parameter is only set by the debug code in one case
+void os::print_location(outputStream* st, intptr_t x, bool print_pc) {
+  address addr = (address)x;
+  CodeBlob* b = CodeCache::find_blob_unsafe(addr);
+  if (b != NULL) {
+    if (b->is_buffer_blob()) {
+      // the interpreter is generated into a buffer blob
+      InterpreterCodelet* i = Interpreter::codelet_containing(addr);
+      if (i != NULL) {
+        i->print_on(st);
+        return;
+      }
+      if (Interpreter::contains(addr)) {
+        st->print_cr(INTPTR_FORMAT " is pointing into interpreter code"
+                     " (not bytecode specific)", addr);
+        return;
+      }
+      //
+      if (AdapterHandlerLibrary::contains(b)) {
+        st->print_cr("Printing AdapterHandler");
+        AdapterHandlerLibrary::print_handler_on(st, b);
+      }
+      // the stubroutines are generated into a buffer blob
+      StubCodeDesc* d = StubCodeDesc::desc_for(addr);
+      if (d != NULL) {
+        d->print_on(st);
+        if (print_pc) st->cr();
+        return;
+      }
+      if (StubRoutines::contains(addr)) {
+        st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) "
+                     "stub routine", addr);
+        return;
+      }
+      // the InlineCacheBuffer is using stubs generated into a buffer blob
+      if (InlineCacheBuffer::contains(addr)) {
+        st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
+        return;
+      }
+      VtableStub* v = VtableStubs::stub_containing(addr);
+      if (v != NULL) {
+        v->print_on(st);
+        return;
+      }
+    }
+    if (print_pc && b->is_nmethod()) {
+      ResourceMark rm;
+      st->print("%#p: Compiled ", addr);
+      ((nmethod*)b)->method()->print_value_on(st);
+      st->print("  = (CodeBlob*)" INTPTR_FORMAT, b);
+      st->cr();
+      return;
+    }
+    if ( b->is_nmethod()) {
+      if (b->is_zombie()) {
+        st->print_cr(INTPTR_FORMAT " is zombie nmethod", b);
+      } else if (b->is_not_entrant()) {
+        st->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b);
+      }
+    }
+    b->print_on(st);
+    return;
+  }
+
+  if (Universe::heap()->is_in(addr)) {
+    HeapWord* p = Universe::heap()->block_start(addr);
+    bool print = false;
+    // If we couldn't find it it just may mean that heap wasn't parseable
+    // See if we were just given an oop directly
+    if (p != NULL && Universe::heap()->block_is_obj(p)) {
+      print = true;
+    } else if (p == NULL && ((oopDesc*)addr)->is_oop()) {
+      p = (HeapWord*) addr;
+      print = true;
+    }
+    if (print) {
+      oop(p)->print_on(st);
+      if (p != (HeapWord*)x && oop(p)->is_constMethod() &&
+          constMethodOop(p)->contains(addr)) {
+        Thread *thread = Thread::current();
+        HandleMark hm(thread);
+        methodHandle mh (thread, constMethodOop(p)->method());
+        if (!mh->is_native()) {
+          st->print_cr("bci_from(%p) = %d; print_codes():",
+                        addr, mh->bci_from(address(x)));
+          mh->print_codes_on(st);
+        }
+      }
+      return;
+    }
+  } else {
+    if (Universe::heap()->is_in_reserved(addr)) {
+      st->print_cr(INTPTR_FORMAT " is an unallocated location "
+                   "in the heap", addr);
+      return;
+    }
+  }
+  if (JNIHandles::is_global_handle((jobject) addr)) {
+    st->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
+    return;
+  }
+  if (JNIHandles::is_weak_global_handle((jobject) addr)) {
+    st->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
+    return;
+  }
+#ifndef PRODUCT
+  // we don't keep the block list in product mode
+  if (JNIHandleBlock::any_contains((jobject) addr)) {
+    st->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
+    return;
+  }
+#endif
+
+  for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+    // Check for privilege stack
+    if (thread->privileged_stack_top() != NULL &&
+        thread->privileged_stack_top()->contains(addr)) {
+      st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack "
+                   "for thread: " INTPTR_FORMAT, addr, thread);
+      thread->print_on(st);
+      return;
+    }
+    // If the addr is a java thread print information about that.
+    if (addr == (address)thread) {
+      thread->print_on(st);
+      return;
+    }
+    // If the addr is in the stack region for this thread then report that
+    // and print thread info
+    if (thread->stack_base() >= addr &&
+        addr > (thread->stack_base() - thread->stack_size())) {
+      st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: "
+                   INTPTR_FORMAT, addr, thread);
+      thread->print_on(st);
+      return;
+    }
+
+  }
+  // Try an OS specific find
+  if (os::find(addr, st)) {
+    return;
+  }
+
+  st->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
+}
 
 // Looks like all platforms except IA64 can use the same function to check
 // if C stack is walkable beyond current frame. The check for fp() is not
--- a/hotspot/src/share/vm/runtime/os.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/os.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,8 +78,10 @@
   }
 
  public:
-  static void init(void);   // Called before command line parsing
-  static jint init_2(void); // Called after command line parsing
+
+  static void init(void);                      // Called before command line parsing
+  static jint init_2(void);                    // Called after command line parsing
+  static void init_3(void);                    // Called at the end of vm init
 
   // File names are case-insensitive on windows only
   // Override me as needed
@@ -322,7 +324,8 @@
     pgc_thread,        // Parallel GC thread
     java_thread,
     compiler_thread,
-    watcher_thread
+    watcher_thread,
+    os_thread
   };
 
   static bool create_thread(Thread* thread,
@@ -451,6 +454,8 @@
   static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
   static void print_date_and_time(outputStream* st);
 
+  static void print_location(outputStream* st, intptr_t x, bool print_pc = false);
+
   // The following two functions are used by fatal error handler to trace
   // native (C) frames. They are not part of frame.hpp/frame.cpp because
   // frame.hpp/cpp assume thread is JavaThread, and also because different
@@ -480,6 +485,9 @@
   // Fills in path to jvm.dll/libjvm.so (this info used to find hpi).
   static void     jvm_path(char *buf, jint buflen);
 
+  // Returns true if we are running in a headless jre.
+  static bool     is_headless_jre();
+
   // JNI names
   static void     print_jni_name_prefix_on(outputStream* st, int args_size);
   static void     print_jni_name_suffix_on(outputStream* st, int args_size);
@@ -580,8 +588,8 @@
   // Platform dependent stuff
   #include "incls/_os_pd.hpp.incl"
 
-  // debugging support (mostly used by debug.cpp)
-  static bool find(address pc) PRODUCT_RETURN0; // OS specific function to make sense out of an address
+  // debugging support (mostly used by debug.cpp but also fatal error handler)
+  static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address
 
   static bool dont_yield();                     // when true, JVM_Yield() is nop
   static void print_statistics();
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -191,6 +191,121 @@
   return ((jdouble)fmod((double)x,(double)y));
 JRT_END
 
+#ifdef __SOFTFP__
+JRT_LEAF(jfloat, SharedRuntime::fadd(jfloat x, jfloat y))
+  return x + y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::fsub(jfloat x, jfloat y))
+  return x - y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::fmul(jfloat x, jfloat y))
+  return x * y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::fdiv(jfloat x, jfloat y))
+  return x / y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::dadd(jdouble x, jdouble y))
+  return x + y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::dsub(jdouble x, jdouble y))
+  return x - y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::dmul(jdouble x, jdouble y))
+  return x * y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::ddiv(jdouble x, jdouble y))
+  return x / y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::i2f(jint x))
+  return (jfloat)x;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::i2d(jint x))
+  return (jdouble)x;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::f2d(jfloat x))
+  return (jdouble)x;
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::fcmpl(float x, float y))
+  return x>y ? 1 : (x==y ? 0 : -1);  /* x<y or is_nan*/
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::fcmpg(float x, float y))
+  return x<y ? -1 : (x==y ? 0 : 1);  /* x>y or is_nan */
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::dcmpl(double x, double y))
+  return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan */
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::dcmpg(double x, double y))
+  return x<y ? -1 : (x==y ? 0 : 1);  /* x>y or is_nan */
+JRT_END
+
+// Functions to return the opposite of the aeabi functions for nan.
+JRT_LEAF(int, SharedRuntime::unordered_fcmplt(float x, float y))
+  return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmplt(double x, double y))
+  return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_fcmple(float x, float y))
+  return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmple(double x, double y))
+  return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_fcmpge(float x, float y))
+  return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmpge(double x, double y))
+  return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_fcmpgt(float x, float y))
+  return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmpgt(double x, double y))
+  return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+// Intrinsics make gcc generate code for these.
+float  SharedRuntime::fneg(float f)   {
+  return -f;
+}
+
+double SharedRuntime::dneg(double f)  {
+  return -f;
+}
+
+#endif // __SOFTFP__
+
+#if defined(__SOFTFP__) || defined(E500V2)
+// Intrinsics make gcc generate code for these.
+double SharedRuntime::dabs(double f)  {
+  return (f <= (double)0.0) ? (double)0.0 - f : f;
+}
+
+double SharedRuntime::dsqrt(double f) {
+  return sqrt(f);
+}
+#endif
 
 JRT_LEAF(jint, SharedRuntime::f2i(jfloat  x))
   if (g_isnan(x))
@@ -2046,6 +2161,8 @@
 int AdapterHandlerTable::_hits;
 int AdapterHandlerTable::_compact;
 
+#endif
+
 class AdapterHandlerTableIterator : public StackObj {
  private:
   AdapterHandlerTable* _table;
@@ -2081,7 +2198,6 @@
     }
   }
 };
-#endif
 
 
 // ---------------------------------------------------------------------------
@@ -2619,7 +2735,6 @@
   FREE_C_HEAP_ARRAY(intptr_t,buf);
 JRT_END
 
-#ifndef PRODUCT
 bool AdapterHandlerLibrary::contains(CodeBlob* b) {
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
@@ -2629,21 +2744,24 @@
   return false;
 }
 
-void AdapterHandlerLibrary::print_handler(CodeBlob* b) {
+void AdapterHandlerLibrary::print_handler_on(outputStream* st, CodeBlob* b) {
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
     AdapterHandlerEntry* a = iter.next();
     if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) {
-      tty->print("Adapter for signature: ");
-      tty->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
-                    a->fingerprint()->as_string(),
-                    a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry());
+      st->print("Adapter for signature: ");
+      st->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
+                   a->fingerprint()->as_string(),
+                   a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry());
+
       return;
     }
   }
   assert(false, "Should have found handler");
 }
 
+#ifndef PRODUCT
+
 void AdapterHandlerLibrary::print_statistics() {
   _adapters->print_statistics();
 }
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -78,6 +78,18 @@
   static jfloat  frem(jfloat  x, jfloat  y);
   static jdouble drem(jdouble x, jdouble y);
 
+#ifdef __SOFTFP__
+  static jfloat  fadd(jfloat x, jfloat y);
+  static jfloat  fsub(jfloat x, jfloat y);
+  static jfloat  fmul(jfloat x, jfloat y);
+  static jfloat  fdiv(jfloat x, jfloat y);
+
+  static jdouble dadd(jdouble x, jdouble y);
+  static jdouble dsub(jdouble x, jdouble y);
+  static jdouble dmul(jdouble x, jdouble y);
+  static jdouble ddiv(jdouble x, jdouble y);
+#endif // __SOFTFP__
+
   // float conversion (needs to set appropriate rounding mode)
   static jint    f2i (jfloat  x);
   static jlong   f2l (jfloat  x);
@@ -87,6 +99,12 @@
   static jfloat  l2f (jlong   x);
   static jdouble l2d (jlong   x);
 
+#ifdef __SOFTFP__
+  static jfloat  i2f (jint    x);
+  static jdouble i2d (jint    x);
+  static jdouble f2d (jfloat  x);
+#endif // __SOFTFP__
+
   // double trigonometrics and transcendentals
   static jdouble dsin(jdouble x);
   static jdouble dcos(jdouble x);
@@ -96,6 +114,32 @@
   static jdouble dexp(jdouble x);
   static jdouble dpow(jdouble x, jdouble y);
 
+#if defined(__SOFTFP__) || defined(E500V2)
+  static double dabs(double f);
+  static double dsqrt(double f);
+#endif
+
+#ifdef __SOFTFP__
+  // C++ compiler generates soft float instructions as well as passing
+  // float and double in registers.
+  static int  fcmpl(float x, float y);
+  static int  fcmpg(float x, float y);
+  static int  dcmpl(double x, double y);
+  static int  dcmpg(double x, double y);
+
+  static int unordered_fcmplt(float x, float y);
+  static int unordered_dcmplt(double x, double y);
+  static int unordered_fcmple(float x, float y);
+  static int unordered_dcmple(double x, double y);
+  static int unordered_fcmpge(float x, float y);
+  static int unordered_dcmpge(double x, double y);
+  static int unordered_fcmpgt(float x, float y);
+  static int unordered_dcmpgt(double x, double y);
+
+  static float  fneg(float f);
+  static double dneg(double f);
+#endif
+
   // exception handling across interpreter/compiler boundaries
   static address raw_exception_handler_for_return_address(JavaThread* thread, address return_address);
   static address exception_handler_for_return_address(JavaThread* thread, address return_address);
@@ -585,9 +629,7 @@
   bool compare_code(unsigned char* code, int length, int total_args_passed, BasicType* sig_bt);
 #endif
 
-#ifndef PRODUCT
   void print();
-#endif /* PRODUCT */
 };
 
 class AdapterHandlerLibrary: public AllStatic {
@@ -609,9 +651,10 @@
   static nmethod* create_dtrace_nmethod (methodHandle method);
 #endif // HAVE_DTRACE_H
 
+  static void print_handler(CodeBlob* b) { print_handler_on(tty, b); }
+  static void print_handler_on(outputStream* st, CodeBlob* b);
+  static bool contains(CodeBlob* b);
 #ifndef PRODUCT
-  static void print_handler(CodeBlob* b);
-  static bool contains(CodeBlob* b);
   static void print_statistics();
 #endif /* PRODUCT */
 
--- a/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -572,7 +572,11 @@
       if(hy<0) z = one/z;       /* z = (1/|x|) */
       if(hx<0) {
         if(((ix-0x3ff00000)|yisint)==0) {
+#ifdef CAN_USE_NAN_DEFINE
+          z = NAN;
+#else
           z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+#endif
         } else if(yisint==1)
           z = -1.0*z;           /* (x<0)**odd = -(|x|**odd) */
       }
@@ -583,7 +587,12 @@
   n = (hx>>31)+1;
 
   /* (x<0)**(non-int) is NaN */
-  if((n|yisint)==0) return (x-x)/(x-x);
+  if((n|yisint)==0)
+#ifdef CAN_USE_NAN_DEFINE
+    return NAN;
+#else
+    return (x-x)/(x-x);
+#endif
 
   s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
   if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
--- a/hotspot/src/share/vm/runtime/signature.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/signature.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -275,11 +275,7 @@
 
   void do_bool  ()                     { pass_int();    _jni_offset++; _offset++;       }
   void do_char  ()                     { pass_int();    _jni_offset++; _offset++;       }
-#if defined(_LP64) || defined(ZERO)
   void do_float ()                     { pass_float();  _jni_offset++; _offset++;       }
-#else
-  void do_float ()                     { pass_int();    _jni_offset++; _offset++;       }
-#endif
 #ifdef _LP64
   void do_double()                     { pass_double(); _jni_offset++; _offset += 2;    }
 #else
@@ -306,9 +302,7 @@
   virtual void pass_int()              = 0;
   virtual void pass_long()             = 0;
   virtual void pass_object()           = 0;
-#if defined(_LP64) || defined(ZERO)
   virtual void pass_float()            = 0;
-#endif
 #ifdef _LP64
   virtual void pass_double()           = 0;
 #else
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -53,15 +53,13 @@
 }
 
 
-void StubCodeDesc::print() {
-  tty->print(group());
-  tty->print("::");
-  tty->print(name());
-  tty->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", begin(), end(), size_in_bytes());
+void StubCodeDesc::print_on(outputStream* st) const {
+  st->print(group());
+  st->print("::");
+  st->print(name());
+  st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT "[ (%d bytes)", begin(), end(), size_in_bytes());
 }
 
-
-
 // Implementation of StubCodeGenerator
 
 StubCodeGenerator::StubCodeGenerator(CodeBuffer* code) {
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -79,7 +79,8 @@
   address     end() const                        { return _end; }
   int         size_in_bytes() const              { return _end - _begin; }
   bool        contains(address pc) const         { return _begin <= pc && pc < _end; }
-  void        print();
+  void        print_on(outputStream* st) const;
+  void        print() const                      { print_on(tty); }
 };
 
 // The base class for all stub-generating code generators.
--- a/hotspot/src/share/vm/runtime/thread.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -807,7 +807,7 @@
 // should be revisited, and they should be removed if possible.
 
 bool Thread::is_lock_owned(address adr) const {
-  return (_stack_base >= adr && adr >= (_stack_base - _stack_size));
+  return on_local_stack(adr);
 }
 
 bool Thread::set_as_starting_thread() {
@@ -1020,7 +1020,7 @@
 // timer interrupts exists on the platform.
 
 WatcherThread* WatcherThread::_watcher_thread   = NULL;
-bool           WatcherThread::_should_terminate = false;
+volatile bool  WatcherThread::_should_terminate = false;
 
 WatcherThread::WatcherThread() : Thread() {
   assert(watcher_thread() == NULL, "we can only allocate one WatcherThread");
@@ -1052,8 +1052,26 @@
 
     // Calculate how long it'll be until the next PeriodicTask work
     // should be done, and sleep that amount of time.
-    const size_t time_to_wait = PeriodicTask::time_to_wait();
-    os::sleep(this, time_to_wait, false);
+    size_t time_to_wait = PeriodicTask::time_to_wait();
+
+    // we expect this to timeout - we only ever get unparked when
+    // we should terminate
+    {
+      OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */);
+
+      jlong prev_time = os::javaTimeNanos();
+      for (;;) {
+        int res= _SleepEvent->park(time_to_wait);
+        if (res == OS_TIMEOUT || _should_terminate)
+          break;
+        // spurious wakeup of some kind
+        jlong now = os::javaTimeNanos();
+        time_to_wait -= (now - prev_time) / 1000000;
+        if (time_to_wait <= 0)
+          break;
+        prev_time = now;
+      }
+    }
 
     if (is_error_reported()) {
       // A fatal error has happened, the error handler(VMError::report_and_die)
@@ -1115,6 +1133,12 @@
   // it is ok to take late safepoints here, if needed
   MutexLocker mu(Terminator_lock);
   _should_terminate = true;
+  OrderAccess::fence();  // ensure WatcherThread sees update in main loop
+
+  Thread* watcher = watcher_thread();
+  if (watcher != NULL)
+    watcher->_SleepEvent->unpark();
+
   while(watcher_thread() != NULL) {
     // This wait should make safepoint checks, wait without a timeout,
     // and wait as a suspend-equivalent condition.
@@ -1364,6 +1388,8 @@
 
   this->create_stack_guard_pages();
 
+  this->cache_global_variables();
+
   // Thread is now sufficient initialized to be handled by the safepoint code as being
   // in the VM. Change thread state from _thread_new to _thread_in_vm
   ThreadStateTransition::transition_and_fence(this, _thread_new, _thread_in_vm);
@@ -2955,6 +2981,9 @@
     return status;
   }
 
+  // Should be done after the heap is fully created
+  main_thread->cache_global_variables();
+
   HandleMark hm;
 
   { MutexLocker mu(Threads_lock);
@@ -3230,6 +3259,9 @@
     WatcherThread::start();
   }
 
+  // Give os specific code one last chance to start
+  os::init_3();
+
   create_vm_timer.end();
   return JNI_OK;
 }
@@ -3249,12 +3281,18 @@
     char buffer[JVM_MAXPATHLEN];
     char ebuf[1024];
     const char *name = agent->name();
+    const char *msg = "Could not find agent library ";
 
     if (agent->is_absolute_path()) {
       library = hpi::dll_load(name, ebuf, sizeof ebuf);
       if (library == NULL) {
+        const char *sub_msg = " in absolute path, with error: ";
+        size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
+        char *buf = NEW_C_HEAP_ARRAY(char, len);
+        jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
         // If we can't find the agent, exit.
-        vm_exit_during_initialization("Could not find agent library in absolute path", name);
+        vm_exit_during_initialization(buf, NULL);
+        FREE_C_HEAP_ARRAY(char, buf);
       }
     } else {
       // Try to load the agent from the standard dll directory
@@ -3267,17 +3305,17 @@
         char *home  = Arguments::get_java_home();
         const char *fmt   = "%s/bin/java %s -Dkernel.background.download=false"
                       " sun.jkernel.DownloadManager -download client_jvm";
-        int length = strlen(props) + strlen(home) + strlen(fmt) + 1;
-        char *cmd = AllocateHeap(length);
+        size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1;
+        char *cmd = NEW_C_HEAP_ARRAY(char, length);
         jio_snprintf(cmd, length, fmt, home, props);
         int status = os::fork_and_exec(cmd);
         FreeHeap(props);
-        FreeHeap(cmd);
         if (status == -1) {
           warning(cmd);
           vm_exit_during_initialization("fork_and_exec failed: %s",
                                          strerror(errno));
         }
+        FREE_C_HEAP_ARRAY(char, cmd);
         // when this comes back the instrument.dll should be where it belongs.
         library = hpi::dll_load(buffer, ebuf, sizeof ebuf);
       }
@@ -3287,8 +3325,13 @@
         hpi::dll_build_name(buffer, sizeof(buffer), ns, name);
         library = hpi::dll_load(buffer, ebuf, sizeof ebuf);
         if (library == NULL) {
+          const char *sub_msg = " on the library path, with error: ";
+          size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
+          char *buf = NEW_C_HEAP_ARRAY(char, len);
+          jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
           // If we can't find the agent, exit.
-          vm_exit_during_initialization("Could not find agent library on the library path or in the local directory", name);
+          vm_exit_during_initialization(buf, NULL);
+          FREE_C_HEAP_ARRAY(char, buf);
         }
       }
     }
--- a/hotspot/src/share/vm/runtime/thread.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -410,9 +410,6 @@
   // Sweeper support
   void nmethods_do(CodeBlobClosure* cf);
 
-  // Tells if adr belong to this thread. This is used
-  // for checking if a lock is owned by the running thread.
-
   // Used by fast lock support
   virtual bool is_lock_owned(address adr) const;
 
@@ -449,6 +446,11 @@
   void    set_stack_size(size_t size)  { _stack_size = size; }
   void    record_stack_base_and_size();
 
+  bool    on_local_stack(address adr) const {
+    /* QQQ this has knowledge of direction, ought to be a stack method */
+    return (_stack_base >= adr && adr >= (_stack_base - _stack_size));
+  }
+
   int     lgrp_id() const                 { return _lgrp_id; }
   void    set_lgrp_id(int value)          { _lgrp_id = value; }
 
@@ -609,7 +611,7 @@
  private:
   static WatcherThread* _watcher_thread;
 
-  static bool _should_terminate;
+  volatile static bool _should_terminate; // updated without holding lock
  public:
   enum SomeConstants {
     delay_interval = 10                          // interrupt delay in milliseconds
@@ -839,6 +841,10 @@
     return (struct JNINativeInterface_ *)_jni_environment.functions;
   }
 
+  // This function is called at thread creation to allow
+  // platform specific thread variables to be initialized.
+  void cache_global_variables();
+
   // Executes Shutdown.shutdown()
   void invoke_shutdown_hooks();
 
--- a/hotspot/src/share/vm/runtime/vm_version.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,11 @@
   #define VMTYPE "Server"
 #else // TIERED
 #ifdef ZERO
+#ifdef SHARK
+  #define VMTYPE "Shark"
+#else // SHARK
   #define VMTYPE "Zero"
+#endif // SHARK
 #else // ZERO
    #define VMTYPE COMPILER1_PRESENT("Client")   \
                   COMPILER2_PRESENT("Server")
@@ -152,6 +156,8 @@
 #define CPU      IA32_ONLY("x86")                \
                  IA64_ONLY("ia64")               \
                  AMD64_ONLY("amd64")             \
+                 ARM_ONLY("arm")                 \
+                 PPC_ONLY("ppc")                 \
                  SPARC_ONLY("sparc")
 #endif // ZERO
 
--- a/hotspot/src/share/vm/runtime/vm_version.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/runtime/vm_version.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -70,6 +70,9 @@
     return _logical_processors_per_package;
   }
 
+  // ARCH specific policy for the BiasedLocking
+  static bool use_biased_locking()  { return true; }
+
   // Number of page sizes efficiently supported by the hardware.  Most chips now
   // support two sizes, thus this default implementation.  Processor-specific
   // subclasses should define new versions to hide this one as needed.  Note
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/llvmHeaders.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifdef assert
+  #undef assert
+#endif
+
+#ifdef DEBUG
+  #define SHARK_DEBUG
+  #undef DEBUG
+#endif
+
+#include <llvm/Argument.h>
+#include <llvm/Constants.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+#include <llvm/Instructions.h>
+#include <llvm/LLVMContext.h>
+#include <llvm/Module.h>
+#if SHARK_LLVM_VERSION < 27
+#include <llvm/ModuleProvider.h>
+#endif
+#include <llvm/Support/IRBuilder.h>
+#include <llvm/System/Threading.h>
+#include <llvm/Target/TargetSelect.h>
+#include <llvm/Type.h>
+#include <llvm/ExecutionEngine/JITMemoryManager.h>
+#include <llvm/Support/CommandLine.h>
+#if SHARK_LLVM_VERSION >= 27
+#include <llvm/ExecutionEngine/JIT.h>
+#include <llvm/ADT/StringMap.h>
+#include <llvm/Support/Debug.h>
+#include <llvm/System/Host.h>
+#endif
+
+#include <map>
+
+#ifdef assert
+  #undef assert
+#endif
+
+// from hotspot/src/share/vm/utilities/debug.hpp
+#ifdef ASSERT
+#ifndef USE_REPEATED_ASSERTS
+#define assert(p, msg)                                                       \
+do {                                                                         \
+  if (!(p)) {                                                                \
+    report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg);       \
+    BREAKPOINT;                                                              \
+  }                                                                          \
+} while (0)
+#else // #ifndef USE_REPEATED_ASSERTS
+#define assert(p, msg)
+do {                                                                         \
+  for (int __i = 0; __i < AssertRepeat; __i++) {                             \
+    if (!(p)) {                                                              \
+      report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg);     \
+      BREAKPOINT;                                                            \
+    }                                                                        \
+  }                                                                          \
+} while (0)
+#endif // #ifndef USE_REPEATED_ASSERTS
+#else
+  #define assert(p, msg)
+#endif
+
+#ifdef DEBUG
+  #undef DEBUG
+#endif
+#ifdef SHARK_DEBUG
+  #define DEBUG
+  #undef SHARK_DEBUG
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/llvmValue.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class LLVMValue : public AllStatic {
+ public:
+  static llvm::ConstantInt* jbyte_constant(jbyte value)
+  {
+    return llvm::ConstantInt::get(SharkType::jbyte_type(), value, true);
+  }
+  static llvm::ConstantInt* jint_constant(jint value)
+  {
+    return llvm::ConstantInt::get(SharkType::jint_type(), value, true);
+  }
+  static llvm::ConstantInt* jlong_constant(jlong value)
+  {
+    return llvm::ConstantInt::get(SharkType::jlong_type(), value, true);
+  }
+  static llvm::ConstantFP* jfloat_constant(jfloat value)
+  {
+    return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value));
+  }
+  static llvm::ConstantFP* jdouble_constant(jdouble value)
+  {
+    return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value));
+  }
+  static llvm::ConstantPointerNull* null()
+  {
+    return llvm::ConstantPointerNull::get(SharkType::oop_type());
+  }
+
+ public:
+  static llvm::ConstantInt* bit_constant(int value)
+  {
+    return llvm::ConstantInt::get(SharkType::bit_type(), value, false);
+  }
+  static llvm::ConstantInt* intptr_constant(intptr_t value)
+  {
+    return llvm::ConstantInt::get(SharkType::intptr_type(), value, false);
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBlock.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,1260 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkBlock.cpp.incl"
+
+using namespace llvm;
+
+void SharkBlock::parse_bytecode(int start, int limit) {
+  SharkValue *a, *b, *c, *d;
+  int i;
+
+  // Ensure the current state is initialized before we emit any code,
+  // so that any setup code for the state is at the start of the block
+  current_state();
+
+  // Parse the bytecodes
+  iter()->reset_to_bci(start);
+  while (iter()->next_bci() < limit) {
+    NOT_PRODUCT(a = b = c = d = NULL);
+    iter()->next();
+
+    if (SharkTraceBytecodes)
+      tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc()));
+
+    if (has_trap() && trap_bci() == bci()) {
+      do_trap(trap_request());
+      return;
+    }
+
+    if (UseLoopSafepoints) {
+      // XXX if a lcmp is followed by an if_?? then C2 maybe-inserts
+      // the safepoint before the lcmp rather than before the if.
+      // Maybe we should do this too.  See parse2.cpp for details.
+      switch (bc()) {
+      case Bytecodes::_goto:
+      case Bytecodes::_ifnull:
+      case Bytecodes::_ifnonnull:
+      case Bytecodes::_if_acmpeq:
+      case Bytecodes::_if_acmpne:
+      case Bytecodes::_ifeq:
+      case Bytecodes::_ifne:
+      case Bytecodes::_iflt:
+      case Bytecodes::_ifle:
+      case Bytecodes::_ifgt:
+      case Bytecodes::_ifge:
+      case Bytecodes::_if_icmpeq:
+      case Bytecodes::_if_icmpne:
+      case Bytecodes::_if_icmplt:
+      case Bytecodes::_if_icmple:
+      case Bytecodes::_if_icmpgt:
+      case Bytecodes::_if_icmpge:
+        if (iter()->get_dest() <= bci())
+          maybe_add_backedge_safepoint();
+        break;
+
+      case Bytecodes::_goto_w:
+        if (iter()->get_far_dest() <= bci())
+          maybe_add_backedge_safepoint();
+        break;
+
+      case Bytecodes::_tableswitch:
+      case Bytecodes::_lookupswitch:
+        if (switch_default_dest() <= bci()) {
+          maybe_add_backedge_safepoint();
+          break;
+        }
+        int len = switch_table_length();
+        for (int i = 0; i < len; i++) {
+          if (switch_dest(i) <= bci()) {
+            maybe_add_backedge_safepoint();
+            break;
+          }
+        }
+        break;
+      }
+    }
+
+    switch (bc()) {
+    case Bytecodes::_nop:
+      break;
+
+    case Bytecodes::_aconst_null:
+      push(SharkValue::null());
+      break;
+
+    case Bytecodes::_iconst_m1:
+      push(SharkValue::jint_constant(-1));
+      break;
+    case Bytecodes::_iconst_0:
+      push(SharkValue::jint_constant(0));
+      break;
+    case Bytecodes::_iconst_1:
+      push(SharkValue::jint_constant(1));
+      break;
+    case Bytecodes::_iconst_2:
+      push(SharkValue::jint_constant(2));
+      break;
+    case Bytecodes::_iconst_3:
+      push(SharkValue::jint_constant(3));
+      break;
+    case Bytecodes::_iconst_4:
+      push(SharkValue::jint_constant(4));
+      break;
+    case Bytecodes::_iconst_5:
+      push(SharkValue::jint_constant(5));
+      break;
+
+    case Bytecodes::_lconst_0:
+      push(SharkValue::jlong_constant(0));
+      break;
+    case Bytecodes::_lconst_1:
+      push(SharkValue::jlong_constant(1));
+      break;
+
+    case Bytecodes::_fconst_0:
+      push(SharkValue::jfloat_constant(0));
+      break;
+    case Bytecodes::_fconst_1:
+      push(SharkValue::jfloat_constant(1));
+      break;
+    case Bytecodes::_fconst_2:
+      push(SharkValue::jfloat_constant(2));
+      break;
+
+    case Bytecodes::_dconst_0:
+      push(SharkValue::jdouble_constant(0));
+      break;
+    case Bytecodes::_dconst_1:
+      push(SharkValue::jdouble_constant(1));
+      break;
+
+    case Bytecodes::_bipush:
+      push(SharkValue::jint_constant(iter()->get_constant_u1()));
+      break;
+    case Bytecodes::_sipush:
+      push(SharkValue::jint_constant(iter()->get_constant_u2()));
+      break;
+
+    case Bytecodes::_ldc:
+    case Bytecodes::_ldc_w:
+    case Bytecodes::_ldc2_w:
+      push(SharkConstant::for_ldc(iter())->value(builder()));
+      break;
+
+    case Bytecodes::_iload_0:
+    case Bytecodes::_lload_0:
+    case Bytecodes::_fload_0:
+    case Bytecodes::_dload_0:
+    case Bytecodes::_aload_0:
+      push(local(0));
+      break;
+    case Bytecodes::_iload_1:
+    case Bytecodes::_lload_1:
+    case Bytecodes::_fload_1:
+    case Bytecodes::_dload_1:
+    case Bytecodes::_aload_1:
+      push(local(1));
+      break;
+    case Bytecodes::_iload_2:
+    case Bytecodes::_lload_2:
+    case Bytecodes::_fload_2:
+    case Bytecodes::_dload_2:
+    case Bytecodes::_aload_2:
+      push(local(2));
+      break;
+    case Bytecodes::_iload_3:
+    case Bytecodes::_lload_3:
+    case Bytecodes::_fload_3:
+    case Bytecodes::_dload_3:
+    case Bytecodes::_aload_3:
+      push(local(3));
+      break;
+    case Bytecodes::_iload:
+    case Bytecodes::_lload:
+    case Bytecodes::_fload:
+    case Bytecodes::_dload:
+    case Bytecodes::_aload:
+      push(local(iter()->get_index()));
+      break;
+
+    case Bytecodes::_baload:
+      do_aload(T_BYTE);
+      break;
+    case Bytecodes::_caload:
+      do_aload(T_CHAR);
+      break;
+    case Bytecodes::_saload:
+      do_aload(T_SHORT);
+      break;
+    case Bytecodes::_iaload:
+      do_aload(T_INT);
+      break;
+    case Bytecodes::_laload:
+      do_aload(T_LONG);
+      break;
+    case Bytecodes::_faload:
+      do_aload(T_FLOAT);
+      break;
+    case Bytecodes::_daload:
+      do_aload(T_DOUBLE);
+      break;
+    case Bytecodes::_aaload:
+      do_aload(T_OBJECT);
+      break;
+
+    case Bytecodes::_istore_0:
+    case Bytecodes::_lstore_0:
+    case Bytecodes::_fstore_0:
+    case Bytecodes::_dstore_0:
+    case Bytecodes::_astore_0:
+      set_local(0, pop());
+      break;
+    case Bytecodes::_istore_1:
+    case Bytecodes::_lstore_1:
+    case Bytecodes::_fstore_1:
+    case Bytecodes::_dstore_1:
+    case Bytecodes::_astore_1:
+      set_local(1, pop());
+      break;
+    case Bytecodes::_istore_2:
+    case Bytecodes::_lstore_2:
+    case Bytecodes::_fstore_2:
+    case Bytecodes::_dstore_2:
+    case Bytecodes::_astore_2:
+      set_local(2, pop());
+      break;
+    case Bytecodes::_istore_3:
+    case Bytecodes::_lstore_3:
+    case Bytecodes::_fstore_3:
+    case Bytecodes::_dstore_3:
+    case Bytecodes::_astore_3:
+      set_local(3, pop());
+      break;
+    case Bytecodes::_istore:
+    case Bytecodes::_lstore:
+    case Bytecodes::_fstore:
+    case Bytecodes::_dstore:
+    case Bytecodes::_astore:
+      set_local(iter()->get_index(), pop());
+      break;
+
+    case Bytecodes::_bastore:
+      do_astore(T_BYTE);
+      break;
+    case Bytecodes::_castore:
+      do_astore(T_CHAR);
+      break;
+    case Bytecodes::_sastore:
+      do_astore(T_SHORT);
+      break;
+    case Bytecodes::_iastore:
+      do_astore(T_INT);
+      break;
+    case Bytecodes::_lastore:
+      do_astore(T_LONG);
+      break;
+    case Bytecodes::_fastore:
+      do_astore(T_FLOAT);
+      break;
+    case Bytecodes::_dastore:
+      do_astore(T_DOUBLE);
+      break;
+    case Bytecodes::_aastore:
+      do_astore(T_OBJECT);
+      break;
+
+    case Bytecodes::_pop:
+      xpop();
+      break;
+    case Bytecodes::_pop2:
+      xpop();
+      xpop();
+      break;
+    case Bytecodes::_swap:
+      a = xpop();
+      b = xpop();
+      xpush(a);
+      xpush(b);
+      break;
+    case Bytecodes::_dup:
+      a = xpop();
+      xpush(a);
+      xpush(a);
+      break;
+    case Bytecodes::_dup_x1:
+      a = xpop();
+      b = xpop();
+      xpush(a);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup_x2:
+      a = xpop();
+      b = xpop();
+      c = xpop();
+      xpush(a);
+      xpush(c);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup2:
+      a = xpop();
+      b = xpop();
+      xpush(b);
+      xpush(a);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup2_x1:
+      a = xpop();
+      b = xpop();
+      c = xpop();
+      xpush(b);
+      xpush(a);
+      xpush(c);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup2_x2:
+      a = xpop();
+      b = xpop();
+      c = xpop();
+      d = xpop();
+      xpush(b);
+      xpush(a);
+      xpush(d);
+      xpush(c);
+      xpush(b);
+      xpush(a);
+      break;
+
+    case Bytecodes::_arraylength:
+      do_arraylength();
+      break;
+
+    case Bytecodes::_getfield:
+      do_getfield();
+      break;
+    case Bytecodes::_getstatic:
+      do_getstatic();
+      break;
+    case Bytecodes::_putfield:
+      do_putfield();
+      break;
+    case Bytecodes::_putstatic:
+      do_putstatic();
+      break;
+
+    case Bytecodes::_iadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAdd(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_isub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateSub(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_imul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateMul(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_idiv:
+      do_idiv();
+      break;
+    case Bytecodes::_irem:
+      do_irem();
+      break;
+    case Bytecodes::_ineg:
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateNeg(a->jint_value()), a->zero_checked()));
+      break;
+    case Bytecodes::_ishl:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateShl(
+          a->jint_value(),
+          builder()->CreateAnd(
+            b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
+      break;
+    case Bytecodes::_ishr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          a->jint_value(),
+          builder()->CreateAnd(
+            b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
+      break;
+    case Bytecodes::_iushr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateLShr(
+          a->jint_value(),
+          builder()->CreateAnd(
+            b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
+      break;
+    case Bytecodes::_iand:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAnd(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_ior:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateOr(a->jint_value(), b->jint_value()),
+        a->zero_checked() && b->zero_checked()));
+      break;
+    case Bytecodes::_ixor:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateXor(a->jint_value(), b->jint_value()), false));
+      break;
+
+    case Bytecodes::_ladd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAdd(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_lsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateSub(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_lmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateMul(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_ldiv:
+      do_ldiv();
+      break;
+    case Bytecodes::_lrem:
+      do_lrem();
+      break;
+    case Bytecodes::_lneg:
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateNeg(a->jlong_value()), a->zero_checked()));
+      break;
+    case Bytecodes::_lshl:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateShl(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            builder()->CreateAnd(
+              b->jint_value(), LLVMValue::jint_constant(0x3f)),
+            SharkType::jlong_type(), true)), false));
+      break;
+    case Bytecodes::_lshr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAShr(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            builder()->CreateAnd(
+              b->jint_value(), LLVMValue::jint_constant(0x3f)),
+            SharkType::jlong_type(), true)), false));
+      break;
+    case Bytecodes::_lushr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateLShr(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            builder()->CreateAnd(
+              b->jint_value(), LLVMValue::jint_constant(0x3f)),
+            SharkType::jlong_type(), true)), false));
+      break;
+    case Bytecodes::_land:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAnd(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_lor:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateOr(a->jlong_value(), b->jlong_value()),
+        a->zero_checked() && b->zero_checked()));
+      break;
+    case Bytecodes::_lxor:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateXor(a->jlong_value(), b->jlong_value()), false));
+      break;
+
+    case Bytecodes::_fadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFAdd(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFSub(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFMul(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fdiv:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFDiv(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_frem:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFRem(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fneg:
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFNeg(a->jfloat_value())));
+      break;
+
+    case Bytecodes::_dadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFAdd(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFSub(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFMul(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_ddiv:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFDiv(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_drem:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFRem(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dneg:
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFNeg(a->jdouble_value())));
+      break;
+
+    case Bytecodes::_iinc:
+      i = iter()->get_index();
+      set_local(
+        i,
+        SharkValue::create_jint(
+          builder()->CreateAdd(
+            LLVMValue::jint_constant(iter()->get_iinc_con()),
+            local(i)->jint_value()), false));
+      break;
+
+    case Bytecodes::_lcmp:
+      do_lcmp();
+      break;
+
+    case Bytecodes::_fcmpl:
+      do_fcmp(false, false);
+      break;
+    case Bytecodes::_fcmpg:
+      do_fcmp(false, true);
+      break;
+    case Bytecodes::_dcmpl:
+      do_fcmp(true, false);
+      break;
+    case Bytecodes::_dcmpg:
+      do_fcmp(true, true);
+      break;
+
+    case Bytecodes::_i2l:
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateIntCast(
+          a->jint_value(), SharkType::jlong_type(), true), a->zero_checked()));
+      break;
+    case Bytecodes::_i2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateSIToFP(
+          pop()->jint_value(), SharkType::jfloat_type())));
+      break;
+    case Bytecodes::_i2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateSIToFP(
+          pop()->jint_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_l2i:
+      push(SharkValue::create_jint(
+        builder()->CreateIntCast(
+          pop()->jlong_value(), SharkType::jint_type(), true), false));
+      break;
+    case Bytecodes::_l2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateSIToFP(
+          pop()->jlong_value(), SharkType::jfloat_type())));
+      break;
+    case Bytecodes::_l2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateSIToFP(
+          pop()->jlong_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_f2i:
+      push(SharkValue::create_jint(
+        builder()->CreateCall(
+          builder()->f2i(), pop()->jfloat_value()), false));
+      break;
+    case Bytecodes::_f2l:
+      push(SharkValue::create_jlong(
+        builder()->CreateCall(
+          builder()->f2l(), pop()->jfloat_value()), false));
+      break;
+    case Bytecodes::_f2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateFPExt(
+          pop()->jfloat_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_d2i:
+      push(SharkValue::create_jint(
+        builder()->CreateCall(
+          builder()->d2i(), pop()->jdouble_value()), false));
+      break;
+    case Bytecodes::_d2l:
+      push(SharkValue::create_jlong(
+        builder()->CreateCall(
+          builder()->d2l(), pop()->jdouble_value()), false));
+      break;
+    case Bytecodes::_d2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateFPTrunc(
+          pop()->jdouble_value(), SharkType::jfloat_type())));
+      break;
+
+    case Bytecodes::_i2b:
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          builder()->CreateShl(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(24)),
+          LLVMValue::jint_constant(24)), false));
+      break;
+    case Bytecodes::_i2c:
+      push(SharkValue::create_jint(
+        builder()->CreateAnd(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(0xffff)), false));
+      break;
+    case Bytecodes::_i2s:
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          builder()->CreateShl(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(16)),
+          LLVMValue::jint_constant(16)), false));
+      break;
+
+    case Bytecodes::_return:
+      do_return(T_VOID);
+      break;
+    case Bytecodes::_ireturn:
+      do_return(T_INT);
+      break;
+    case Bytecodes::_lreturn:
+      do_return(T_LONG);
+      break;
+    case Bytecodes::_freturn:
+      do_return(T_FLOAT);
+      break;
+    case Bytecodes::_dreturn:
+      do_return(T_DOUBLE);
+      break;
+    case Bytecodes::_areturn:
+      do_return(T_OBJECT);
+      break;
+
+    case Bytecodes::_athrow:
+      do_athrow();
+      break;
+
+    case Bytecodes::_goto:
+    case Bytecodes::_goto_w:
+      do_goto();
+      break;
+
+    case Bytecodes::_jsr:
+    case Bytecodes::_jsr_w:
+      do_jsr();
+      break;
+
+    case Bytecodes::_ret:
+      do_ret();
+      break;
+
+    case Bytecodes::_ifnull:
+      do_if(ICmpInst::ICMP_EQ, SharkValue::null(), pop());
+      break;
+    case Bytecodes::_ifnonnull:
+      do_if(ICmpInst::ICMP_NE, SharkValue::null(), pop());
+      break;
+    case Bytecodes::_if_acmpeq:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_EQ, b, a);
+      break;
+    case Bytecodes::_if_acmpne:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_NE, b, a);
+      break;
+    case Bytecodes::_ifeq:
+      do_if(ICmpInst::ICMP_EQ, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifne:
+      do_if(ICmpInst::ICMP_NE, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_iflt:
+      do_if(ICmpInst::ICMP_SLT, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifle:
+      do_if(ICmpInst::ICMP_SLE, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifgt:
+      do_if(ICmpInst::ICMP_SGT, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifge:
+      do_if(ICmpInst::ICMP_SGE, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_if_icmpeq:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_EQ, b, a);
+      break;
+    case Bytecodes::_if_icmpne:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_NE, b, a);
+      break;
+    case Bytecodes::_if_icmplt:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SLT, b, a);
+      break;
+    case Bytecodes::_if_icmple:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SLE, b, a);
+      break;
+    case Bytecodes::_if_icmpgt:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SGT, b, a);
+      break;
+    case Bytecodes::_if_icmpge:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SGE, b, a);
+      break;
+
+    case Bytecodes::_tableswitch:
+    case Bytecodes::_lookupswitch:
+      do_switch();
+      break;
+
+    case Bytecodes::_invokestatic:
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_invokeinterface:
+      do_call();
+      break;
+
+    case Bytecodes::_instanceof:
+      // This is a very common construct:
+      //
+      //  if (object instanceof Klass) {
+      //    something = (Klass) object;
+      //    ...
+      //  }
+      //
+      // which gets compiled to something like this:
+      //
+      //  28: aload 9
+      //  30: instanceof <Class Klass>
+      //  33: ifeq 52
+      //  36: aload 9
+      //  38: checkcast <Class Klass>
+      //
+      // Handling both bytecodes at once allows us
+      // to eliminate the checkcast.
+      if (iter()->next_bci() < limit &&
+          (iter()->next_bc() == Bytecodes::_ifeq ||
+           iter()->next_bc() == Bytecodes::_ifne) &&
+          (!UseLoopSafepoints ||
+           iter()->next_get_dest() > iter()->next_bci())) {
+        if (maybe_do_instanceof_if()) {
+          iter()->next();
+          if (SharkTraceBytecodes)
+            tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc()));
+          break;
+        }
+      }
+      // fall through
+    case Bytecodes::_checkcast:
+      do_instance_check();
+      break;
+
+    case Bytecodes::_new:
+      do_new();
+      break;
+    case Bytecodes::_newarray:
+      do_newarray();
+      break;
+    case Bytecodes::_anewarray:
+      do_anewarray();
+      break;
+    case Bytecodes::_multianewarray:
+      do_multianewarray();
+      break;
+
+    case Bytecodes::_monitorenter:
+      do_monitorenter();
+      break;
+    case Bytecodes::_monitorexit:
+      do_monitorexit();
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+  }
+}
+
+SharkState* SharkBlock::initial_current_state() {
+  return entry_state()->copy();
+}
+
+int SharkBlock::switch_default_dest() {
+  return iter()->get_dest_table(0);
+}
+
+int SharkBlock::switch_table_length() {
+  switch(bc()) {
+  case Bytecodes::_tableswitch:
+    return iter()->get_int_table(2) - iter()->get_int_table(1) + 1;
+
+  case Bytecodes::_lookupswitch:
+    return iter()->get_int_table(1);
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+int SharkBlock::switch_key(int i) {
+  switch(bc()) {
+  case Bytecodes::_tableswitch:
+    return iter()->get_int_table(1) + i;
+
+  case Bytecodes::_lookupswitch:
+    return iter()->get_int_table(2 + 2 * i);
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+int SharkBlock::switch_dest(int i) {
+  switch(bc()) {
+  case Bytecodes::_tableswitch:
+    return iter()->get_dest_table(i + 3);
+
+  case Bytecodes::_lookupswitch:
+    return iter()->get_dest_table(2 + 2 * i + 1);
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+void SharkBlock::do_div_or_rem(bool is_long, bool is_rem) {
+  SharkValue *sb = pop();
+  SharkValue *sa = pop();
+
+  check_divide_by_zero(sb);
+
+  Value *a, *b, *p, *q;
+  if (is_long) {
+    a = sa->jlong_value();
+    b = sb->jlong_value();
+    p = LLVMValue::jlong_constant(0x8000000000000000LL);
+    q = LLVMValue::jlong_constant(-1);
+  }
+  else {
+    a = sa->jint_value();
+    b = sb->jint_value();
+    p = LLVMValue::jint_constant(0x80000000);
+    q = LLVMValue::jint_constant(-1);
+  }
+
+  BasicBlock *ip           = builder()->GetBlockInsertionPoint();
+  BasicBlock *special_case = builder()->CreateBlock(ip, "special_case");
+  BasicBlock *general_case = builder()->CreateBlock(ip, "general_case");
+  BasicBlock *done         = builder()->CreateBlock(ip, "done");
+
+  builder()->CreateCondBr(
+    builder()->CreateAnd(
+      builder()->CreateICmpEQ(a, p),
+      builder()->CreateICmpEQ(b, q)),
+    special_case, general_case);
+
+  builder()->SetInsertPoint(special_case);
+  Value *special_result;
+  if (is_rem) {
+    if (is_long)
+      special_result = LLVMValue::jlong_constant(0);
+    else
+      special_result = LLVMValue::jint_constant(0);
+  }
+  else {
+    special_result = a;
+  }
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(general_case);
+  Value *general_result;
+  if (is_rem)
+    general_result = builder()->CreateSRem(a, b);
+  else
+    general_result = builder()->CreateSDiv(a, b);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result;
+  if (is_long)
+    result = builder()->CreatePHI(SharkType::jlong_type(), "result");
+  else
+    result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(special_result, special_case);
+  result->addIncoming(general_result, general_case);
+
+  if (is_long)
+    push(SharkValue::create_jlong(result, false));
+  else
+    push(SharkValue::create_jint(result, false));
+}
+
+void SharkBlock::do_field_access(bool is_get, bool is_field) {
+  bool will_link;
+  ciField *field = iter()->get_field(will_link);
+  assert(will_link, "typeflow responsibility");
+  assert(is_field != field->is_static(), "mismatch");
+
+  // Pop the value off the stack where necessary
+  SharkValue *value = NULL;
+  if (!is_get)
+    value = pop();
+
+  // Find the object we're accessing, if necessary
+  Value *object = NULL;
+  if (is_field) {
+    SharkValue *value = pop();
+    check_null(value);
+    object = value->generic_value();
+  }
+  if (is_get && field->is_constant()) {
+    SharkConstant *constant = SharkConstant::for_field(iter());
+    if (constant->is_loaded())
+      value = constant->value(builder());
+  }
+  if (!is_get || value == NULL) {
+    if (!is_field)
+      object = builder()->CreateInlineOop(field->holder());
+
+    BasicType   basic_type = field->type()->basic_type();
+    const Type *stack_type = SharkType::to_stackType(basic_type);
+    const Type *field_type = SharkType::to_arrayType(basic_type);
+
+    Value *addr = builder()->CreateAddressOfStructEntry(
+      object, in_ByteSize(field->offset_in_bytes()),
+      PointerType::getUnqual(field_type),
+      "addr");
+
+    // Do the access
+    if (is_get) {
+      Value *field_value = builder()->CreateLoad(addr);
+
+      if (field_type != stack_type) {
+        field_value = builder()->CreateIntCast(
+          field_value, stack_type, basic_type != T_CHAR);
+      }
+
+      value = SharkValue::create_generic(field->type(), field_value, false);
+    }
+    else {
+      Value *field_value = value->generic_value();
+
+      if (field_type != stack_type) {
+        field_value = builder()->CreateIntCast(
+          field_value, field_type, basic_type != T_CHAR);
+      }
+
+      builder()->CreateStore(field_value, addr);
+
+      if (!field->type()->is_primitive_type())
+        builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
+
+      if (field->is_volatile())
+        builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD);
+    }
+  }
+
+  // Push the value onto the stack where necessary
+  if (is_get)
+    push(value);
+}
+
+void SharkBlock::do_lcmp() {
+  Value *b = pop()->jlong_value();
+  Value *a = pop()->jlong_value();
+
+  BasicBlock *ip   = builder()->GetBlockInsertionPoint();
+  BasicBlock *ne   = builder()->CreateBlock(ip, "lcmp_ne");
+  BasicBlock *lt   = builder()->CreateBlock(ip, "lcmp_lt");
+  BasicBlock *gt   = builder()->CreateBlock(ip, "lcmp_gt");
+  BasicBlock *done = builder()->CreateBlock(ip, "done");
+
+  BasicBlock *eq = builder()->GetInsertBlock();
+  builder()->CreateCondBr(builder()->CreateICmpEQ(a, b), done, ne);
+
+  builder()->SetInsertPoint(ne);
+  builder()->CreateCondBr(builder()->CreateICmpSLT(a, b), lt, gt);
+
+  builder()->SetInsertPoint(lt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(gt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(LLVMValue::jint_constant(-1), lt);
+  result->addIncoming(LLVMValue::jint_constant(0),  eq);
+  result->addIncoming(LLVMValue::jint_constant(1),  gt);
+
+  push(SharkValue::create_jint(result, false));
+}
+
+void SharkBlock::do_fcmp(bool is_double, bool unordered_is_greater) {
+  Value *a, *b;
+  if (is_double) {
+    b = pop()->jdouble_value();
+    a = pop()->jdouble_value();
+  }
+  else {
+    b = pop()->jfloat_value();
+    a = pop()->jfloat_value();
+  }
+
+  BasicBlock *ip      = builder()->GetBlockInsertionPoint();
+  BasicBlock *ordered = builder()->CreateBlock(ip, "ordered");
+  BasicBlock *ge      = builder()->CreateBlock(ip, "fcmp_ge");
+  BasicBlock *lt      = builder()->CreateBlock(ip, "fcmp_lt");
+  BasicBlock *eq      = builder()->CreateBlock(ip, "fcmp_eq");
+  BasicBlock *gt      = builder()->CreateBlock(ip, "fcmp_gt");
+  BasicBlock *done    = builder()->CreateBlock(ip, "done");
+
+  builder()->CreateCondBr(
+    builder()->CreateFCmpUNO(a, b),
+    unordered_is_greater ? gt : lt, ordered);
+
+  builder()->SetInsertPoint(ordered);
+  builder()->CreateCondBr(builder()->CreateFCmpULT(a, b), lt, ge);
+
+  builder()->SetInsertPoint(ge);
+  builder()->CreateCondBr(builder()->CreateFCmpUGT(a, b), gt, eq);
+
+  builder()->SetInsertPoint(lt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(gt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(eq);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(LLVMValue::jint_constant(-1), lt);
+  result->addIncoming(LLVMValue::jint_constant(0),  eq);
+  result->addIncoming(LLVMValue::jint_constant(1),  gt);
+
+  push(SharkValue::create_jint(result, false));
+}
+
+void SharkBlock::emit_IR() {
+  ShouldNotCallThis();
+}
+
+SharkState* SharkBlock::entry_state() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_zero_check(SharkValue* value) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::maybe_add_backedge_safepoint() {
+  ShouldNotCallThis();
+}
+
+bool SharkBlock::has_trap() {
+  return false;
+}
+
+int SharkBlock::trap_request() {
+  ShouldNotCallThis();
+}
+
+int SharkBlock::trap_bci() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_trap(int trap_request) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_arraylength() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_aload(BasicType basic_type) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_astore(BasicType basic_type) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_return(BasicType type) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_athrow() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_goto() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_jsr() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_ret() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_if(ICmpInst::Predicate p, SharkValue* b, SharkValue* a) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_switch() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_call() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_instance_check() {
+  ShouldNotCallThis();
+}
+
+bool SharkBlock::maybe_do_instanceof_if() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_new() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_newarray() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_anewarray() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_multianewarray() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_monitorenter() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_monitorexit() {
+  ShouldNotCallThis();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBlock.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkState;
+
+class SharkBlock : public SharkTargetInvariants {
+ protected:
+  SharkBlock(const SharkTargetInvariants* parent)
+    : SharkTargetInvariants(parent),
+      _iter(target()),
+      _current_state(NULL) {}
+
+  SharkBlock(const SharkCompileInvariants* parent, ciMethod* target)
+    : SharkTargetInvariants(parent, target),
+      _iter(target),
+      _current_state(NULL) {}
+
+ private:
+  ciBytecodeStream _iter;
+  SharkState*      _current_state;
+
+ public:
+  ciBytecodeStream* iter() {
+    return &_iter;
+  }
+  Bytecodes::Code bc() {
+    return iter()->cur_bc();
+  }
+  int bci() {
+    return iter()->cur_bci();
+  }
+
+  // Entry state
+ protected:
+  virtual SharkState* entry_state();
+
+  // Current state
+ private:
+  SharkState* initial_current_state();
+
+ public:
+  SharkState* current_state() {
+    if (_current_state == NULL)
+      set_current_state(initial_current_state());
+    return _current_state;
+  }
+
+ protected:
+  void set_current_state(SharkState* current_state) {
+    _current_state = current_state;
+  }
+
+  // Local variables
+ protected:
+  SharkValue* local(int index) {
+    SharkValue *value = current_state()->local(index);
+    assert(value != NULL, "shouldn't be");
+    assert(value->is_one_word() ||
+           (index + 1 < max_locals() &&
+            current_state()->local(index + 1) == NULL), "should be");
+    return value;
+  }
+  void set_local(int index, SharkValue* value) {
+    assert(value != NULL, "shouldn't be");
+    current_state()->set_local(index, value);
+    if (value->is_two_word())
+      current_state()->set_local(index + 1, NULL);
+  }
+
+  // Expression stack (raw)
+ protected:
+  void xpush(SharkValue* value) {
+    current_state()->push(value);
+  }
+  SharkValue* xpop() {
+    return current_state()->pop();
+  }
+  SharkValue* xstack(int slot) {
+    SharkValue *value = current_state()->stack(slot);
+    assert(value != NULL, "shouldn't be");
+    assert(value->is_one_word() ||
+           (slot > 0 &&
+            current_state()->stack(slot - 1) == NULL), "should be");
+    return value;
+  }
+  int xstack_depth() {
+    return current_state()->stack_depth();
+  }
+
+  // Expression stack (cooked)
+ protected:
+  void push(SharkValue* value) {
+    assert(value != NULL, "shouldn't be");
+    xpush(value);
+    if (value->is_two_word())
+      xpush(NULL);
+  }
+  SharkValue* pop() {
+    int size = current_state()->stack(0) == NULL ? 2 : 1;
+    if (size == 2)
+      xpop();
+    SharkValue *value = xpop();
+    assert(value && value->size() == size, "should be");
+    return value;
+  }
+  SharkValue* pop_result(BasicType type) {
+    SharkValue *result = pop();
+
+#ifdef ASSERT
+    switch (result->basic_type()) {
+    case T_BOOLEAN:
+    case T_BYTE:
+    case T_CHAR:
+    case T_SHORT:
+      assert(type == T_INT, "type mismatch");
+      break;
+
+    case T_ARRAY:
+      assert(type == T_OBJECT, "type mismatch");
+      break;
+
+    default:
+      assert(result->basic_type() == type, "type mismatch");
+    }
+#endif // ASSERT
+
+    return result;
+  }
+
+  // Code generation
+ public:
+  virtual void emit_IR();
+
+ protected:
+  void parse_bytecode(int start, int limit);
+
+  // Helpers
+ protected:
+  virtual void do_zero_check(SharkValue* value);
+
+  // Zero checking
+ protected:
+  void check_null(SharkValue* object) {
+    zero_check(object);
+  }
+  void check_divide_by_zero(SharkValue* value) {
+    zero_check(value);
+  }
+ private:
+  void zero_check(SharkValue* value) {
+    if (!value->zero_checked())
+      do_zero_check(value);
+  }
+
+  // Safepoints
+ protected:
+  virtual void maybe_add_backedge_safepoint();
+
+  // Traps
+ protected:
+  virtual bool has_trap();
+  virtual int  trap_request();
+  virtual int  trap_bci();
+  virtual void do_trap(int trap_request);
+
+  // arraylength
+ protected:
+  virtual void do_arraylength();
+
+  // *aload and *astore
+ protected:
+  virtual void do_aload(BasicType basic_type);
+  virtual void do_astore(BasicType basic_type);
+
+  // *div and *rem
+ private:
+  void do_idiv() {
+    do_div_or_rem(false, false);
+  }
+  void do_irem() {
+    do_div_or_rem(false, true);
+  }
+  void do_ldiv() {
+    do_div_or_rem(true, false);
+  }
+  void do_lrem() {
+    do_div_or_rem(true, true);
+  }
+  void do_div_or_rem(bool is_long, bool is_rem);
+
+  // get* and put*
+ private:
+  void do_getstatic() {
+    do_field_access(true, false);
+  }
+  void do_getfield() {
+    do_field_access(true, true);
+  }
+  void do_putstatic() {
+    do_field_access(false, false);
+  }
+  void do_putfield() {
+    do_field_access(false, true);
+  }
+  void do_field_access(bool is_get, bool is_field);
+
+  // lcmp and [fd]cmp[lg]
+ private:
+  void do_lcmp();
+  void do_fcmp(bool is_double, bool unordered_is_greater);
+
+  // *return and athrow
+ protected:
+  virtual void do_return(BasicType type);
+  virtual void do_athrow();
+
+  // goto*
+ protected:
+  virtual void do_goto();
+
+  // jsr* and ret
+ protected:
+  virtual void do_jsr();
+  virtual void do_ret();
+
+  // if*
+ protected:
+  virtual void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
+
+  // *switch
+ protected:
+  int switch_default_dest();
+  int switch_table_length();
+  int switch_key(int i);
+  int switch_dest(int i);
+
+  virtual void do_switch();
+
+  // invoke*
+ protected:
+  virtual void do_call();
+
+  // checkcast and instanceof
+ protected:
+  virtual void do_instance_check();
+  virtual bool maybe_do_instanceof_if();
+
+  // new and *newarray
+ protected:
+  virtual void do_new();
+  virtual void do_newarray();
+  virtual void do_anewarray();
+  virtual void do_multianewarray();
+
+  // monitorenter and monitorexit
+ protected:
+  virtual void do_monitorenter();
+  virtual void do_monitorexit();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBuilder.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,591 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkBuilder.cpp.incl"
+
+using namespace llvm;
+
+SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer)
+  : IRBuilder<>(SharkContext::current()),
+    _code_buffer(code_buffer) {
+}
+
+// Helpers for accessing structures
+Value* SharkBuilder::CreateAddressOfStructEntry(Value*      base,
+                                                ByteSize    offset,
+                                                const Type* type,
+                                                const char* name) {
+  return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name);
+}
+
+LoadInst* SharkBuilder::CreateValueOfStructEntry(Value*      base,
+                                                 ByteSize    offset,
+                                                 const Type* type,
+                                                 const char* name) {
+  return CreateLoad(
+    CreateAddressOfStructEntry(
+      base, offset, PointerType::getUnqual(type)),
+    name);
+}
+
+// Helpers for accessing arrays
+
+LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) {
+  return CreateValueOfStructEntry(
+    arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
+    SharkType::jint_type(), "length");
+}
+
+Value* SharkBuilder::CreateArrayAddress(Value*      arrayoop,
+                                        const Type* element_type,
+                                        int         element_bytes,
+                                        ByteSize    base_offset,
+                                        Value*      index,
+                                        const char* name) {
+  Value* offset = CreateIntCast(index, SharkType::intptr_type(), false);
+  if (element_bytes != 1)
+    offset = CreateShl(
+      offset,
+      LLVMValue::intptr_constant(exact_log2(element_bytes)));
+  offset = CreateAdd(
+    LLVMValue::intptr_constant(in_bytes(base_offset)), offset);
+
+  return CreateIntToPtr(
+    CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
+    PointerType::getUnqual(element_type),
+    name);
+}
+
+Value* SharkBuilder::CreateArrayAddress(Value*      arrayoop,
+                                        BasicType   basic_type,
+                                        ByteSize    base_offset,
+                                        Value*      index,
+                                        const char* name) {
+  return CreateArrayAddress(
+    arrayoop,
+    SharkType::to_arrayType(basic_type),
+    type2aelembytes(basic_type),
+    base_offset, index, name);
+}
+
+Value* SharkBuilder::CreateArrayAddress(Value*      arrayoop,
+                                        BasicType   basic_type,
+                                        Value*      index,
+                                        const char* name) {
+  return CreateArrayAddress(
+    arrayoop, basic_type,
+    in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)),
+    index, name);
+}
+
+// Helpers for creating intrinsics and external functions.
+
+const Type* SharkBuilder::make_type(char type, bool void_ok) {
+  switch (type) {
+    // Primitive types
+  case 'c':
+    return SharkType::jbyte_type();
+  case 'i':
+    return SharkType::jint_type();
+  case 'l':
+    return SharkType::jlong_type();
+  case 'x':
+    return SharkType::intptr_type();
+  case 'f':
+    return SharkType::jfloat_type();
+  case 'd':
+    return SharkType::jdouble_type();
+
+    // Pointers to primitive types
+  case 'C':
+  case 'I':
+  case 'L':
+  case 'X':
+  case 'F':
+  case 'D':
+    return PointerType::getUnqual(make_type(tolower(type), false));
+
+    // VM objects
+  case 'T':
+    return SharkType::thread_type();
+  case 'M':
+    return PointerType::getUnqual(SharkType::monitor_type());
+  case 'O':
+    return SharkType::oop_type();
+
+    // Miscellaneous
+  case 'v':
+    assert(void_ok, "should be");
+    return SharkType::void_type();
+  case '1':
+    return SharkType::bit_type();
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+const FunctionType* SharkBuilder::make_ftype(const char* params,
+                                             const char* ret) {
+  std::vector<const Type*> param_types;
+  for (const char* c = params; *c; c++)
+    param_types.push_back(make_type(*c, false));
+
+  assert(strlen(ret) == 1, "should be");
+  const Type *return_type = make_type(*ret, true);
+
+  return FunctionType::get(return_type, param_types, false);
+}
+
+// Create an object representing an intrinsic or external function by
+// referencing the symbol by name.  This is the LLVM-style approach,
+// but it cannot be used on functions within libjvm.so its symbols
+// are not exported.  Note that you cannot make this work simply by
+// exporting the symbols, as some symbols have the same names as
+// symbols in the standard libraries (eg, atan2, fabs) and would
+// obscure them were they visible.
+Value* SharkBuilder::make_function(const char* name,
+                                   const char* params,
+                                   const char* ret) {
+  return SharkContext::current().get_external(name, make_ftype(params, ret));
+}
+
+// Create an object representing an external function by inlining a
+// function pointer in the code.  This is not the LLVM way, but it's
+// the only way to access functions in libjvm.so and functions like
+// __kernel_dmb on ARM which is accessed via an absolute address.
+Value* SharkBuilder::make_function(address     func,
+                                   const char* params,
+                                   const char* ret) {
+  return CreateIntToPtr(
+    LLVMValue::intptr_constant((intptr_t) func),
+    PointerType::getUnqual(make_ftype(params, ret)));
+}
+
+// VM calls
+
+Value* SharkBuilder::find_exception_handler() {
+  return make_function(
+    (address) SharkRuntime::find_exception_handler, "TIi", "i");
+}
+
+Value* SharkBuilder::monitorenter() {
+  return make_function((address) SharkRuntime::monitorenter, "TM", "v");
+}
+
+Value* SharkBuilder::monitorexit() {
+  return make_function((address) SharkRuntime::monitorexit, "TM", "v");
+}
+
+Value* SharkBuilder::new_instance() {
+  return make_function((address) SharkRuntime::new_instance, "Ti", "v");
+}
+
+Value* SharkBuilder::newarray() {
+  return make_function((address) SharkRuntime::newarray, "Tii", "v");
+}
+
+Value* SharkBuilder::anewarray() {
+  return make_function((address) SharkRuntime::anewarray, "Tii", "v");
+}
+
+Value* SharkBuilder::multianewarray() {
+  return make_function((address) SharkRuntime::multianewarray, "TiiI", "v");
+}
+
+Value* SharkBuilder::register_finalizer() {
+  return make_function((address) SharkRuntime::register_finalizer, "TO", "v");
+}
+
+Value* SharkBuilder::safepoint() {
+  return make_function((address) SafepointSynchronize::block, "T", "v");
+}
+
+Value* SharkBuilder::throw_ArithmeticException() {
+  return make_function(
+    (address) SharkRuntime::throw_ArithmeticException, "TCi", "v");
+}
+
+Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() {
+  return make_function(
+    (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v");
+}
+
+Value* SharkBuilder::throw_ClassCastException() {
+  return make_function(
+    (address) SharkRuntime::throw_ClassCastException, "TCi", "v");
+}
+
+Value* SharkBuilder::throw_NullPointerException() {
+  return make_function(
+    (address) SharkRuntime::throw_NullPointerException, "TCi", "v");
+}
+
+// High-level non-VM calls
+
+Value* SharkBuilder::f2i() {
+  return make_function((address) SharedRuntime::f2i, "f", "i");
+}
+
+Value* SharkBuilder::f2l() {
+  return make_function((address) SharedRuntime::f2l, "f", "l");
+}
+
+Value* SharkBuilder::d2i() {
+  return make_function((address) SharedRuntime::d2i, "d", "i");
+}
+
+Value* SharkBuilder::d2l() {
+  return make_function((address) SharedRuntime::d2l, "d", "l");
+}
+
+Value* SharkBuilder::is_subtype_of() {
+  return make_function((address) SharkRuntime::is_subtype_of, "OO", "c");
+}
+
+Value* SharkBuilder::current_time_millis() {
+  return make_function((address) os::javaTimeMillis, "", "l");
+}
+
+Value* SharkBuilder::sin() {
+  return make_function("llvm.sin.f64", "d", "d");
+}
+
+Value* SharkBuilder::cos() {
+  return make_function("llvm.cos.f64", "d", "d");
+}
+
+Value* SharkBuilder::tan() {
+  return make_function((address) ::tan, "d", "d");
+}
+
+Value* SharkBuilder::atan2() {
+  return make_function((address) ::atan2, "dd", "d");
+}
+
+Value* SharkBuilder::sqrt() {
+  return make_function("llvm.sqrt.f64", "d", "d");
+}
+
+Value* SharkBuilder::log() {
+  return make_function("llvm.log.f64", "d", "d");
+}
+
+Value* SharkBuilder::log10() {
+  return make_function("llvm.log10.f64", "d", "d");
+}
+
+Value* SharkBuilder::pow() {
+  return make_function("llvm.pow.f64", "dd", "d");
+}
+
+Value* SharkBuilder::exp() {
+  return make_function("llvm.exp.f64", "d", "d");
+}
+
+Value* SharkBuilder::fabs() {
+  return make_function((address) ::fabs, "d", "d");
+}
+
+Value* SharkBuilder::unsafe_field_offset_to_byte_offset() {
+  extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset);
+  return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l");
+}
+
+Value* SharkBuilder::osr_migration_end() {
+  return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
+}
+
+// Semi-VM calls
+
+Value* SharkBuilder::throw_StackOverflowError() {
+  return make_function((address) ZeroStack::handle_overflow, "T", "v");
+}
+
+Value* SharkBuilder::uncommon_trap() {
+  return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i");
+}
+
+Value* SharkBuilder::deoptimized_entry_point() {
+  return make_function((address) CppInterpreter::main_loop, "iT", "v");
+}
+
+// Native-Java transition
+
+Value* SharkBuilder::check_special_condition_for_native_trans() {
+  return make_function(
+    (address) JavaThread::check_special_condition_for_native_trans,
+    "T", "v");
+}
+
+// Low-level non-VM calls
+
+// The ARM-specific code here is to work around unimplemented
+// atomic exchange and memory barrier intrinsics in LLVM.
+//
+// Delegating to external functions for these would normally
+// incur a speed penalty, but Linux on ARM is a special case
+// in that atomic operations on that platform are handled by
+// external functions anyway.  It would be *preferable* for
+// the calls to be hidden away in LLVM, but it's not hurting
+// performance so having the calls here is acceptable.
+//
+// If you are building Shark on a platform without atomic
+// exchange and/or memory barrier intrinsics then it is only
+// acceptable to mimic this approach if your platform cannot
+// perform these operations without delegating to a function.
+
+#ifdef ARM
+static jint zero_cmpxchg_int(volatile jint *ptr, jint oldval, jint newval) {
+  return Atomic::cmpxchg(newval, ptr, oldval);
+}
+#endif // ARM
+
+Value* SharkBuilder::cmpxchg_int() {
+  return make_function(
+#ifdef ARM
+    (address) zero_cmpxchg_int,
+#else
+    "llvm.atomic.cmp.swap.i32.p0i32",
+#endif // ARM
+    "Iii", "i");
+}
+
+#ifdef ARM
+static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr,
+                                 intptr_t           oldval,
+                                 intptr_t           newval) {
+  return Atomic::cmpxchg_ptr(newval, ptr, oldval);
+}
+#endif // ARM
+
+Value* SharkBuilder::cmpxchg_ptr() {
+  return make_function(
+#ifdef ARM
+    (address) zero_cmpxchg_ptr,
+#else
+    "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32") ".p0i" LP64_ONLY("64") NOT_LP64("32"),
+#endif // ARM
+    "Xxx", "x");
+}
+
+Value* SharkBuilder::frame_address() {
+  return make_function("llvm.frameaddress", "i", "C");
+}
+
+Value* SharkBuilder::memory_barrier() {
+  return make_function(
+#ifdef ARM
+    (address) 0xffff0fa0, // __kernel_dmb
+#else
+    "llvm.memory.barrier",
+#endif // ARM
+    "11111", "v");
+}
+
+Value* SharkBuilder::memset() {
+#if SHARK_LLVM_VERSION >= 28
+  // LLVM 2.8 added a fifth isVolatile field for memset
+  // introduced with LLVM r100304
+  return make_function("llvm.memset.i32", "Cciii", "v");
+#else
+  return make_function("llvm.memset.i32", "Ccii", "v");
+#endif
+}
+
+Value* SharkBuilder::unimplemented() {
+  return make_function((address) report_unimplemented, "Ci", "v");
+}
+
+Value* SharkBuilder::should_not_reach_here() {
+  return make_function((address) report_should_not_reach_here, "Ci", "v");
+}
+
+Value* SharkBuilder::dump() {
+  return make_function((address) SharkRuntime::dump, "Cx", "v");
+}
+
+// Public interface to low-level non-VM calls
+
+CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value,
+                                         Value* dst,
+                                         Value* compare_value) {
+  return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value);
+}
+
+CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value,
+                                         Value* dst,
+                                         Value* compare_value) {
+  return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value);
+}
+
+CallInst* SharkBuilder::CreateGetFrameAddress() {
+  return CreateCall(frame_address(), LLVMValue::jint_constant(0));
+}
+
+CallInst *SharkBuilder::CreateMemoryBarrier(int flags) {
+  Value *args[] = {
+    LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0),
+    LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0),
+    LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0),
+    LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0),
+    LLVMValue::bit_constant(1)};
+
+  return CreateCall(memory_barrier(), args, args + 5);
+}
+
+CallInst* SharkBuilder::CreateMemset(Value* dst,
+                                     Value* value,
+                                     Value* len,
+                                     Value* align) {
+#if SHARK_LLVM_VERSION >= 28
+  return CreateCall5(memset(), dst, value, len, align,
+                     LLVMValue::jint_constant(0));
+#else
+  return CreateCall4(memset(), dst, value, len, align);
+#endif
+}
+
+CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) {
+  return CreateCall2(
+    unimplemented(),
+    CreateIntToPtr(
+      LLVMValue::intptr_constant((intptr_t) file),
+      PointerType::getUnqual(SharkType::jbyte_type())),
+    LLVMValue::jint_constant(line));
+}
+
+CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) {
+  return CreateCall2(
+    should_not_reach_here(),
+    CreateIntToPtr(
+      LLVMValue::intptr_constant((intptr_t) file),
+      PointerType::getUnqual(SharkType::jbyte_type())),
+    LLVMValue::jint_constant(line));
+}
+
+#ifndef PRODUCT
+CallInst* SharkBuilder::CreateDump(Value* value) {
+  const char *name;
+  if (value->hasName())
+    // XXX this leaks, but it's only debug code
+    name = strdup(value->getName().str().c_str());
+  else
+    name = "unnamed_value";
+
+  if (isa<PointerType>(value->getType()))
+    value = CreatePtrToInt(value, SharkType::intptr_type());
+  else if (value->getType()->
+#if SHARK_LLVM_VERSION >= 27
+           isIntegerTy()
+#else
+           isInteger()
+#endif
+           )
+    value = CreateIntCast(value, SharkType::intptr_type(), false);
+  else
+    Unimplemented();
+
+  return CreateCall2(
+    dump(),
+    CreateIntToPtr(
+      LLVMValue::intptr_constant((intptr_t) name),
+      PointerType::getUnqual(SharkType::jbyte_type())),
+    value);
+}
+#endif // PRODUCT
+
+// HotSpot memory barriers
+
+void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) {
+  if (bs->kind() != BarrierSet::CardTableModRef)
+    Unimplemented();
+
+  CreateStore(
+    LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card),
+    CreateIntToPtr(
+      CreateAdd(
+        LLVMValue::intptr_constant(
+          (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base),
+        CreateLShr(
+          CreatePtrToInt(field, SharkType::intptr_type()),
+          LLVMValue::intptr_constant(CardTableModRefBS::card_shift))),
+      PointerType::getUnqual(SharkType::jbyte_type())));
+}
+
+// Helpers for accessing the code buffer
+
+Value* SharkBuilder::code_buffer_address(int offset) {
+  return CreateAdd(
+    code_buffer()->base_pc(),
+    LLVMValue::intptr_constant(offset));
+}
+
+Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) {
+  return CreateLoad(
+    CreateIntToPtr(
+      code_buffer_address(code_buffer()->inline_oop(object)),
+      PointerType::getUnqual(SharkType::oop_type())),
+    name);
+}
+
+Value* SharkBuilder::CreateInlineData(void*       data,
+                                      size_t      size,
+                                      const Type* type,
+                                      const char* name) {
+  return CreateIntToPtr(
+    code_buffer_address(code_buffer()->inline_data(data, size)),
+    type,
+    name);
+}
+
+// Helpers for creating basic blocks.
+
+BasicBlock* SharkBuilder::GetBlockInsertionPoint() const {
+  BasicBlock *cur = GetInsertBlock();
+
+  // BasicBlock::Create takes an insertBefore argument, so
+  // we need to find the block _after_ the current block
+  Function::iterator iter = cur->getParent()->begin();
+  Function::iterator end  = cur->getParent()->end();
+  while (iter != end) {
+    iter++;
+    if (&*iter == cur) {
+      iter++;
+      break;
+    }
+  }
+
+  if (iter == end)
+    return NULL;
+  else
+    return iter;
+}
+
+BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const {
+  return BasicBlock::Create(
+    SharkContext::current(), name, GetInsertBlock()->getParent(), ip);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBuilder.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkBuilder : public llvm::IRBuilder<> {
+  friend class SharkCompileInvariants;
+
+ public:
+  SharkBuilder(SharkCodeBuffer* code_buffer);
+
+  // The code buffer we are building into.
+ private:
+  SharkCodeBuffer* _code_buffer;
+
+ protected:
+  SharkCodeBuffer* code_buffer() const {
+    return _code_buffer;
+  }
+
+  // Helpers for accessing structures.
+ public:
+  llvm::Value* CreateAddressOfStructEntry(llvm::Value* base,
+                                          ByteSize offset,
+                                          const llvm::Type* type,
+                                          const char *name = "");
+  llvm::LoadInst* CreateValueOfStructEntry(llvm::Value* base,
+                                           ByteSize offset,
+                                           const llvm::Type* type,
+                                           const char *name = "");
+
+  // Helpers for accessing arrays.
+ public:
+  llvm::LoadInst* CreateArrayLength(llvm::Value* arrayoop);
+  llvm::Value* CreateArrayAddress(llvm::Value*      arrayoop,
+                                  const llvm::Type* element_type,
+                                  int               element_bytes,
+                                  ByteSize          base_offset,
+                                  llvm::Value*      index,
+                                  const char*       name = "");
+  llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
+                                  BasicType    basic_type,
+                                  ByteSize     base_offset,
+                                  llvm::Value* index,
+                                  const char*  name = "");
+  llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
+                                  BasicType    basic_type,
+                                  llvm::Value* index,
+                                  const char*  name = "");
+
+  // Helpers for creating intrinsics and external functions.
+ private:
+  static const llvm::Type* make_type(char type, bool void_ok);
+  static const llvm::FunctionType* make_ftype(const char* params,
+                                              const char* ret);
+  llvm::Value* make_function(const char* name,
+                             const char* params,
+                             const char* ret);
+  llvm::Value* make_function(address     func,
+                             const char* params,
+                             const char* ret);
+
+  // Intrinsics and external functions, part 1: VM calls.
+  //   These are functions declared with JRT_ENTRY and JRT_EXIT,
+  //   macros which flip the thread from _thread_in_Java to
+  //   _thread_in_vm and back.  VM calls always safepoint, and can
+  //   therefore throw exceptions.  VM calls require of setup and
+  //   teardown, and must be called with SharkTopLevelBlock::call_vm.
+ public:
+  llvm::Value* find_exception_handler();
+  llvm::Value* monitorenter();
+  llvm::Value* monitorexit();
+  llvm::Value* new_instance();
+  llvm::Value* newarray();
+  llvm::Value* anewarray();
+  llvm::Value* multianewarray();
+  llvm::Value* register_finalizer();
+  llvm::Value* safepoint();
+  llvm::Value* throw_ArithmeticException();
+  llvm::Value* throw_ArrayIndexOutOfBoundsException();
+  llvm::Value* throw_ClassCastException();
+  llvm::Value* throw_NullPointerException();
+
+  // Intrinsics and external functions, part 2: High-level non-VM calls.
+  //   These are called like normal functions.  The stack is not set
+  //   up for walking so they must not safepoint or throw exceptions,
+  //   or call anything that might.
+ public:
+  llvm::Value* f2i();
+  llvm::Value* f2l();
+  llvm::Value* d2i();
+  llvm::Value* d2l();
+  llvm::Value* is_subtype_of();
+  llvm::Value* current_time_millis();
+  llvm::Value* sin();
+  llvm::Value* cos();
+  llvm::Value* tan();
+  llvm::Value* atan2();
+  llvm::Value* sqrt();
+  llvm::Value* log();
+  llvm::Value* log10();
+  llvm::Value* pow();
+  llvm::Value* exp();
+  llvm::Value* fabs();
+  llvm::Value* unsafe_field_offset_to_byte_offset();
+  llvm::Value* osr_migration_end();
+
+  // Intrinsics and external functions, part 3: semi-VM calls.
+  //   These are special cases that do VM call stuff but are invoked
+  //   as though they were normal calls.  This is acceptable so long
+  //   as the method that calls them returns to its immediately that
+  //   the semi VM call returns.
+ public:
+  llvm::Value* throw_StackOverflowError();
+  llvm::Value* uncommon_trap();
+  llvm::Value* deoptimized_entry_point();
+
+  // Intrinsics and external functions, part 4: Native-Java transition.
+  //   This is a special case in that it is invoked during a thread
+  //   state transition.  The stack must be set up for walking, and it
+  //   may throw exceptions, but the state is _thread_in_native_trans.
+ public:
+  llvm::Value* check_special_condition_for_native_trans();
+
+  // Intrinsics and external functions, part 5: Low-level non-VM calls.
+  //   These have the same caveats as the high-level non-VM calls
+  //   above.  They are not accessed directly; rather, you should
+  //   access them via the various Create* methods below.
+ private:
+  llvm::Value* cmpxchg_int();
+  llvm::Value* cmpxchg_ptr();
+  llvm::Value* frame_address();
+  llvm::Value* memory_barrier();
+  llvm::Value* memset();
+  llvm::Value* unimplemented();
+  llvm::Value* should_not_reach_here();
+  llvm::Value* dump();
+
+  // Public interface to low-level non-VM calls.
+ public:
+  llvm::CallInst* CreateCmpxchgInt(llvm::Value* exchange_value,
+                                   llvm::Value* dst,
+                                   llvm::Value* compare_value);
+  llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value,
+                                   llvm::Value* dst,
+                                   llvm::Value* compare_value);
+  llvm::CallInst* CreateGetFrameAddress();
+  llvm::CallInst* CreateMemoryBarrier(int flags);
+  llvm::CallInst* CreateMemset(llvm::Value* dst,
+                               llvm::Value* value,
+                               llvm::Value* len,
+                               llvm::Value* align);
+  llvm::CallInst* CreateUnimplemented(const char* file, int line);
+  llvm::CallInst* CreateShouldNotReachHere(const char* file, int line);
+  NOT_PRODUCT(llvm::CallInst* CreateDump(llvm::Value* value));
+
+  // Flags for CreateMemoryBarrier.
+ public:
+  enum BarrierFlags {
+    BARRIER_LOADLOAD   = 1,
+    BARRIER_LOADSTORE  = 2,
+    BARRIER_STORELOAD  = 4,
+    BARRIER_STORESTORE = 8
+  };
+
+  // HotSpot memory barriers
+ public:
+  void CreateUpdateBarrierSet(BarrierSet* bs, llvm::Value* field);
+
+  // Helpers for accessing the code buffer.
+ public:
+  llvm::Value* code_buffer_address(int offset);
+  llvm::Value* CreateInlineOop(jobject object, const char* name = "");
+  llvm::Value* CreateInlineOop(ciObject* object, const char* name = "") {
+    return CreateInlineOop(object->constant_encoding(), name);
+  }
+  llvm::Value* CreateInlineData(void*             data,
+                                size_t            size,
+                                const llvm::Type* type,
+                                const char*       name = "");
+
+  // Helpers for creating basic blocks.
+  // NB don't use unless SharkFunction::CreateBlock is unavailable.
+  // XXX these are hacky and should be removed.
+ public:
+  llvm::BasicBlock* GetBlockInsertionPoint() const;
+  llvm::BasicBlock* CreateBlock(llvm::BasicBlock* ip,
+                                const char*       name="") const;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkCacheDecache.cpp.incl"
+
+using namespace llvm;
+
+void SharkDecacher::start_frame() {
+  // Start recording the debug information
+  _pc_offset = code_buffer()->create_unique_offset();
+  _oopmap = new OopMap(
+    oopmap_slot_munge(stack()->oopmap_frame_size()),
+    oopmap_slot_munge(arg_size()));
+  debug_info()->add_safepoint(pc_offset(), oopmap());
+}
+
+void SharkDecacher::start_stack(int stack_depth) {
+  // Create the array we'll record our stack slots in
+  _exparray = new GrowableArray<ScopeValue*>(stack_depth);
+
+  // Set the stack pointer
+  stack()->CreateStoreStackPointer(
+    builder()->CreatePtrToInt(
+      stack()->slot_addr(
+        stack()->stack_slots_offset() + max_stack() - stack_depth),
+      SharkType::intptr_type()));
+}
+
+void SharkDecacher::process_stack_slot(int          index,
+                                       SharkValue** addr,
+                                       int          offset) {
+  SharkValue *value = *addr;
+
+  // Write the value to the frame if necessary
+  if (stack_slot_needs_write(index, value)) {
+    write_value_to_frame(
+      SharkType::to_stackType(value->basic_type()),
+      value->generic_value(),
+      adjusted_offset(value, offset));
+  }
+
+  // Record the value in the oopmap if necessary
+  if (stack_slot_needs_oopmap(index, value)) {
+    oopmap()->set_oop(slot2reg(offset));
+  }
+
+  // Record the value in the debuginfo if necessary
+  if (stack_slot_needs_debuginfo(index, value)) {
+    exparray()->append(slot2lv(offset, stack_location_type(index, addr)));
+  }
+}
+
+void SharkDecacher::start_monitors(int num_monitors) {
+  // Create the array we'll record our monitors in
+  _monarray = new GrowableArray<MonitorValue*>(num_monitors);
+}
+
+void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) {
+  oopmap()->set_oop(slot2reg(obj_offset));
+
+  monarray()->append(new MonitorValue(
+    slot2lv (obj_offset, Location::oop),
+    slot2loc(box_offset, Location::normal)));
+}
+
+void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) {
+  // Decache the temporary oop slot
+  if (*value) {
+    write_value_to_frame(
+      SharkType::oop_type(),
+      *value,
+      offset);
+
+    oopmap()->set_oop(slot2reg(offset));
+  }
+}
+
+void SharkDecacher::process_method_slot(Value** value, int offset) {
+  // Decache the method pointer
+  write_value_to_frame(
+    SharkType::methodOop_type(),
+    *value,
+    offset);
+
+  oopmap()->set_oop(slot2reg(offset));
+}
+
+void SharkDecacher::process_pc_slot(int offset) {
+  // Record the PC
+  builder()->CreateStore(
+    builder()->code_buffer_address(pc_offset()),
+    stack()->slot_addr(offset));
+}
+
+void SharkDecacher::start_locals() {
+  // Create the array we'll record our local variables in
+  _locarray = new GrowableArray<ScopeValue*>(max_locals());}
+
+void SharkDecacher::process_local_slot(int          index,
+                                       SharkValue** addr,
+                                       int          offset) {
+  SharkValue *value = *addr;
+
+  // Write the value to the frame if necessary
+  if (local_slot_needs_write(index, value)) {
+    write_value_to_frame(
+      SharkType::to_stackType(value->basic_type()),
+      value->generic_value(),
+      adjusted_offset(value, offset));
+  }
+
+  // Record the value in the oopmap if necessary
+  if (local_slot_needs_oopmap(index, value)) {
+    oopmap()->set_oop(slot2reg(offset));
+  }
+
+  // Record the value in the debuginfo if necessary
+  if (local_slot_needs_debuginfo(index, value)) {
+    locarray()->append(slot2lv(offset, local_location_type(index, addr)));
+  }
+}
+
+void SharkDecacher::end_frame() {
+  // Record the scope
+  debug_info()->describe_scope(
+    pc_offset(),
+    target(),
+    bci(),
+    true,
+    false,
+    false,
+    debug_info()->create_scope_values(locarray()),
+    debug_info()->create_scope_values(exparray()),
+    debug_info()->create_monitor_values(monarray()));
+
+  // Finish recording the debug information
+  debug_info()->end_safepoint(pc_offset());
+}
+
+void SharkCacher::process_stack_slot(int          index,
+                                     SharkValue** addr,
+                                     int          offset) {
+  SharkValue *value = *addr;
+
+  // Read the value from the frame if necessary
+  if (stack_slot_needs_read(index, value)) {
+    *addr = SharkValue::create_generic(
+      value->type(),
+      read_value_from_frame(
+        SharkType::to_stackType(value->basic_type()),
+        adjusted_offset(value, offset)),
+      value->zero_checked());
+  }
+}
+
+void SharkOSREntryCacher::process_monitor(int index,
+                                          int box_offset,
+                                          int obj_offset) {
+  // Copy the monitor from the OSR buffer to the frame
+  int src_offset = max_locals() + index * 2;
+  builder()->CreateStore(
+    builder()->CreateLoad(
+      CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
+    stack()->slot_addr(box_offset, SharkType::intptr_type()));
+  builder()->CreateStore(
+    builder()->CreateLoad(
+      CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
+    stack()->slot_addr(obj_offset, SharkType::oop_type()));
+}
+
+void SharkCacher::process_oop_tmp_slot(Value** value, int offset) {
+  // Cache the temporary oop
+  if (*value)
+    *value = read_value_from_frame(SharkType::oop_type(), offset);
+}
+
+void SharkCacher::process_method_slot(Value** value, int offset) {
+  // Cache the method pointer
+  *value = read_value_from_frame(SharkType::methodOop_type(), offset);
+}
+
+void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) {
+  // "Cache" the method pointer
+  *value = method();
+}
+
+void SharkCacher::process_local_slot(int          index,
+                                     SharkValue** addr,
+                                     int          offset) {
+  SharkValue *value = *addr;
+
+  // Read the value from the frame if necessary
+  if (local_slot_needs_read(index, value)) {
+    *addr = SharkValue::create_generic(
+      value->type(),
+      read_value_from_frame(
+        SharkType::to_stackType(value->basic_type()),
+        adjusted_offset(value, offset)),
+      value->zero_checked());
+  }
+}
+
+Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int         offset,
+                                                       const Type* type) {
+  Value *result = builder()->CreateStructGEP(osr_buf(), offset);
+  if (type != SharkType::intptr_type())
+    result = builder()->CreateBitCast(result, PointerType::getUnqual(type));
+  return result;
+}
+
+void SharkOSREntryCacher::process_local_slot(int          index,
+                                             SharkValue** addr,
+                                             int          offset) {
+  SharkValue *value = *addr;
+
+  // Read the value from the OSR buffer if necessary
+  if (local_slot_needs_read(index, value)) {
+    *addr = SharkValue::create_generic(
+      value->type(),
+      builder()->CreateLoad(
+        CreateAddressOfOSRBufEntry(
+          adjusted_offset(value, max_locals() - 1 - index),
+          SharkType::to_stackType(value->basic_type()))),
+      value->zero_checked());
+  }
+}
+
+void SharkDecacher::write_value_to_frame(const Type* type,
+                                         Value*      value,
+                                         int         offset) {
+  builder()->CreateStore(value, stack()->slot_addr(offset, type));
+}
+
+Value* SharkCacher::read_value_from_frame(const Type* type, int offset) {
+  return builder()->CreateLoad(stack()->slot_addr(offset, type));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCacheDecache.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// Class hierarchy:
+// - SharkStateScanner
+//   - SharkCacherDecacher
+//     - SharkDecacher
+//       - SharkJavaCallDecacher
+//       - SharkVMCallDecacher
+//       - SharkTrapDecacher
+//     - SharkCacher
+//       - SharkJavaCallCacher
+//       - SharkVMCallCacher
+//       - SharkFunctionEntryCacher
+//         - SharkNormalEntryCacher
+//         - SharkOSREntryCacher
+
+class SharkCacherDecacher : public SharkStateScanner {
+ protected:
+  SharkCacherDecacher(SharkFunction* function)
+    : SharkStateScanner(function) {}
+
+  // Helper
+ protected:
+  static int adjusted_offset(SharkValue* value, int offset) {
+    if (value->is_two_word())
+      offset--;
+    return offset;
+  }
+};
+
+class SharkDecacher : public SharkCacherDecacher {
+ protected:
+  SharkDecacher(SharkFunction* function, int bci)
+    : SharkCacherDecacher(function), _bci(bci) {}
+
+ private:
+  int _bci;
+
+ protected:
+  int bci() const {
+    return _bci;
+  }
+
+ private:
+  int                           _pc_offset;
+  OopMap*                       _oopmap;
+  GrowableArray<ScopeValue*>*   _exparray;
+  GrowableArray<MonitorValue*>* _monarray;
+  GrowableArray<ScopeValue*>*   _locarray;
+
+ private:
+  int pc_offset() const {
+    return _pc_offset;
+  }
+  OopMap* oopmap() const {
+    return _oopmap;
+  }
+  GrowableArray<ScopeValue*>* exparray() const {
+    return _exparray;
+  }
+  GrowableArray<MonitorValue*>* monarray() const {
+    return _monarray;
+  }
+  GrowableArray<ScopeValue*>* locarray() const {
+    return _locarray;
+  }
+
+  // Callbacks
+ protected:
+  void start_frame();
+
+  void start_stack(int stack_depth);
+  void process_stack_slot(int index, SharkValue** value, int offset);
+
+  void start_monitors(int num_monitors);
+  void process_monitor(int index, int box_offset, int obj_offset);
+
+  void process_oop_tmp_slot(llvm::Value** value, int offset);
+  void process_method_slot(llvm::Value** value, int offset);
+  void process_pc_slot(int offset);
+
+  void start_locals();
+  void process_local_slot(int index, SharkValue** value, int offset);
+
+  void end_frame();
+
+  // oopmap and debuginfo helpers
+ private:
+  static int oopmap_slot_munge(int offset) {
+    return SharkStack::oopmap_slot_munge(offset);
+  }
+  static VMReg slot2reg(int offset) {
+    return SharkStack::slot2reg(offset);
+  }
+  static Location slot2loc(int offset, Location::Type type) {
+    return Location::new_stk_loc(type, offset * wordSize);
+  }
+  static LocationValue* slot2lv(int offset, Location::Type type) {
+    return new LocationValue(slot2loc(offset, type));
+  }
+  static Location::Type location_type(SharkValue** addr, bool maybe_two_word) {
+    // low addresses this end
+    //                           Type       32-bit    64-bit
+    //   ----------------------------------------------------
+    //   stack[0]    local[3]    jobject    oop       oop
+    //   stack[1]    local[2]    NULL       normal    lng
+    //   stack[2]    local[1]    jlong      normal    invalid
+    //   stack[3]    local[0]    jint       normal    normal
+    //
+    // high addresses this end
+
+    SharkValue *value = *addr;
+    if (value) {
+      if (value->is_jobject())
+        return Location::oop;
+#ifdef _LP64
+      if (value->is_two_word())
+        return Location::invalid;
+#endif // _LP64
+      return Location::normal;
+    }
+    else {
+      if (maybe_two_word) {
+        value = *(addr - 1);
+        if (value && value->is_two_word()) {
+#ifdef _LP64
+          if (value->is_jlong())
+            return Location::lng;
+          if (value->is_jdouble())
+            return Location::dbl;
+          ShouldNotReachHere();
+#else
+          return Location::normal;
+#endif // _LP64
+        }
+      }
+      return Location::invalid;
+    }
+  }
+
+  // Stack slot helpers
+ protected:
+  virtual bool stack_slot_needs_write(int index, SharkValue* value) = 0;
+  virtual bool stack_slot_needs_oopmap(int index, SharkValue* value) = 0;
+  virtual bool stack_slot_needs_debuginfo(int index, SharkValue* value) = 0;
+
+  static Location::Type stack_location_type(int index, SharkValue** addr) {
+    return location_type(addr, *addr == NULL);
+  }
+
+  // Local slot helpers
+ protected:
+  virtual bool local_slot_needs_write(int index, SharkValue* value) = 0;
+  virtual bool local_slot_needs_oopmap(int index, SharkValue* value) = 0;
+  virtual bool local_slot_needs_debuginfo(int index, SharkValue* value) = 0;
+
+  static Location::Type local_location_type(int index, SharkValue** addr) {
+    return location_type(addr, index > 0);
+  }
+
+  // Writer helper
+ protected:
+  void write_value_to_frame(const llvm::Type* type,
+                            llvm::Value*      value,
+                            int               offset);
+};
+
+class SharkJavaCallDecacher : public SharkDecacher {
+ public:
+  SharkJavaCallDecacher(SharkFunction* function, int bci, ciMethod* callee)
+    : SharkDecacher(function, bci), _callee(callee) {}
+
+ private:
+  ciMethod* _callee;
+
+ protected:
+  ciMethod* callee() const {
+    return _callee;
+  }
+
+  // Stack slot helpers
+ protected:
+  bool stack_slot_needs_write(int index, SharkValue* value) {
+    return value && (index < callee()->arg_size() || value->is_jobject());
+  }
+  bool stack_slot_needs_oopmap(int index, SharkValue* value) {
+    return value && value->is_jobject() && index >= callee()->arg_size();
+  }
+  bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
+    return index >= callee()->arg_size();
+  }
+
+  // Local slot helpers
+ protected:
+  bool local_slot_needs_write(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool local_slot_needs_oopmap(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool local_slot_needs_debuginfo(int index, SharkValue* value) {
+    return true;
+  }
+};
+
+class SharkVMCallDecacher : public SharkDecacher {
+ public:
+  SharkVMCallDecacher(SharkFunction* function, int bci)
+    : SharkDecacher(function, bci) {}
+
+  // Stack slot helpers
+ protected:
+  bool stack_slot_needs_write(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool stack_slot_needs_oopmap(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
+    return true;
+  }
+
+  // Local slot helpers
+ protected:
+  bool local_slot_needs_write(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool local_slot_needs_oopmap(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool local_slot_needs_debuginfo(int index, SharkValue* value) {
+    return true;
+  }
+};
+
+class SharkTrapDecacher : public SharkDecacher {
+ public:
+  SharkTrapDecacher(SharkFunction* function, int bci)
+    : SharkDecacher(function, bci) {}
+
+  // Stack slot helpers
+ protected:
+  bool stack_slot_needs_write(int index, SharkValue* value) {
+    return value != NULL;
+  }
+  bool stack_slot_needs_oopmap(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
+    return true;
+  }
+
+  // Local slot helpers
+ protected:
+  bool local_slot_needs_write(int index, SharkValue* value) {
+    return value != NULL;
+  }
+  bool local_slot_needs_oopmap(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+  bool local_slot_needs_debuginfo(int index, SharkValue* value) {
+    return true;
+  }
+};
+
+class SharkCacher : public SharkCacherDecacher {
+ protected:
+  SharkCacher(SharkFunction* function)
+    : SharkCacherDecacher(function) {}
+
+  // Callbacks
+ protected:
+  void process_stack_slot(int index, SharkValue** value, int offset);
+
+  void process_oop_tmp_slot(llvm::Value** value, int offset);
+  virtual void process_method_slot(llvm::Value** value, int offset);
+
+  virtual void process_local_slot(int index, SharkValue** value, int offset);
+
+  // Stack slot helper
+ protected:
+  virtual bool stack_slot_needs_read(int index, SharkValue* value) = 0;
+
+  // Local slot helper
+ protected:
+  virtual bool local_slot_needs_read(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+
+  // Writer helper
+ protected:
+  llvm::Value* read_value_from_frame(const llvm::Type* type, int offset);
+};
+
+class SharkJavaCallCacher : public SharkCacher {
+ public:
+  SharkJavaCallCacher(SharkFunction* function, ciMethod* callee)
+    : SharkCacher(function), _callee(callee) {}
+
+ private:
+  ciMethod* _callee;
+
+ protected:
+  ciMethod* callee() const {
+    return _callee;
+  }
+
+  // Stack slot helper
+ protected:
+  bool stack_slot_needs_read(int index, SharkValue* value) {
+    return value && (index < callee()->return_type()->size() ||
+                     value->is_jobject());
+  }
+};
+
+class SharkVMCallCacher : public SharkCacher {
+ public:
+  SharkVMCallCacher(SharkFunction* function)
+    : SharkCacher(function) {}
+
+  // Stack slot helper
+ protected:
+  bool stack_slot_needs_read(int index, SharkValue* value) {
+    return value && value->is_jobject();
+  }
+};
+
+class SharkFunctionEntryCacher : public SharkCacher {
+ public:
+  SharkFunctionEntryCacher(SharkFunction* function, llvm::Value* method)
+    : SharkCacher(function), _method(method) {}
+
+ private:
+  llvm::Value* _method;
+
+ private:
+  llvm::Value* method() const {
+    return _method;
+  }
+
+  // Method slot callback
+ protected:
+  void process_method_slot(llvm::Value** value, int offset);
+
+  // Stack slot helper
+ protected:
+  bool stack_slot_needs_read(int index, SharkValue* value) {
+    ShouldNotReachHere(); // entry block shouldn't have stack
+  }
+
+  // Local slot helper
+ protected:
+  bool local_slot_needs_read(int index, SharkValue* value) {
+    return value != NULL;
+  }
+};
+
+class SharkNormalEntryCacher : public SharkFunctionEntryCacher {
+ public:
+  SharkNormalEntryCacher(SharkFunction* function, llvm::Value* method)
+    : SharkFunctionEntryCacher(function, method) {}
+};
+
+class SharkOSREntryCacher : public SharkFunctionEntryCacher {
+ public:
+  SharkOSREntryCacher(SharkFunction* function,
+                      llvm::Value*   method,
+                      llvm::Value*   osr_buf)
+    : SharkFunctionEntryCacher(function, method),
+      _osr_buf(
+        builder()->CreateBitCast(
+          osr_buf,
+          llvm::PointerType::getUnqual(
+            llvm::ArrayType::get(
+              SharkType::intptr_type(),
+              max_locals() + max_monitors() * 2)))) {}
+
+ private:
+  llvm::Value* _osr_buf;
+
+ private:
+  llvm::Value* osr_buf() const {
+    return _osr_buf;
+  }
+
+  // Callbacks
+ protected:
+  void process_monitor(int index, int box_offset, int obj_offset);
+  void process_local_slot(int index, SharkValue** value, int offset);
+
+  // Helper
+ private:
+  llvm::Value* CreateAddressOfOSRBufEntry(int offset, const llvm::Type* type);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkCodeBuffer : public StackObj {
+ public:
+  SharkCodeBuffer(MacroAssembler* masm)
+    : _masm(masm), _base_pc(NULL) {}
+
+ private:
+  MacroAssembler* _masm;
+  llvm::Value*    _base_pc;
+
+ private:
+  MacroAssembler* masm() const {
+    return _masm;
+  }
+
+ public:
+  llvm::Value* base_pc() const {
+    return _base_pc;
+  }
+  void set_base_pc(llvm::Value* base_pc) {
+    assert(_base_pc == NULL, "only do this once");
+    _base_pc = base_pc;
+  }
+
+  // Allocate some space in the buffer and return its address.
+  // This buffer will have been relocated by the time the method
+  // is installed, so you can't inline the result in code.
+ public:
+  void* malloc(size_t size) const {
+    masm()->align(BytesPerWord);
+    void *result = masm()->pc();
+    masm()->advance(size);
+    return result;
+  }
+
+  // Create a unique offset in the buffer.
+ public:
+  int create_unique_offset() const {
+    int offset = masm()->offset();
+    masm()->advance(1);
+    return offset;
+  }
+
+  // Inline an oop into the buffer and return its offset.
+ public:
+  int inline_oop(jobject object) const {
+    masm()->align(BytesPerWord);
+    int offset = masm()->offset();
+    masm()->store_oop(object);
+    return offset;
+  }
+
+  // Inline a block of non-oop data into the buffer and return its offset.
+ public:
+  int inline_data(void *src, size_t size) const {
+    masm()->align(BytesPerWord);
+    int offset = masm()->offset();
+    void *dst = masm()->pc();
+    masm()->advance(size);
+    memcpy(dst, src, size);
+    return offset;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCompiler.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkCompiler.cpp.incl"
+
+#include <fnmatch.h>
+
+using namespace llvm;
+
+#if SHARK_LLVM_VERSION >= 27
+namespace {
+  cl::opt<std::string>
+  MCPU("mcpu");
+
+  cl::list<std::string>
+  MAttrs("mattr",
+         cl::CommaSeparated);
+}
+#endif
+
+SharkCompiler::SharkCompiler()
+  : AbstractCompiler() {
+  // Create the lock to protect the memory manager and execution engine
+  _execution_engine_lock = new Monitor(Mutex::leaf, "SharkExecutionEngineLock");
+  MutexLocker locker(execution_engine_lock());
+
+  // Make LLVM safe for multithreading
+  if (!llvm_start_multithreaded())
+    fatal("llvm_start_multithreaded() failed");
+
+  // Initialize the native target
+  InitializeNativeTarget();
+
+  // Create the two contexts which we'll use
+  _normal_context = new SharkContext("normal");
+  _native_context = new SharkContext("native");
+
+  // Create the memory manager
+  _memory_manager = new SharkMemoryManager();
+
+#if SHARK_LLVM_VERSION >= 27
+  // Finetune LLVM for the current host CPU.
+  StringMap<bool> Features;
+  bool gotCpuFeatures = llvm::sys::getHostCPUFeatures(Features);
+  std::string cpu("-mcpu=" + llvm::sys::getHostCPUName());
+
+  std::vector<const char*> args;
+  args.push_back(""); // program name
+  args.push_back(cpu.c_str());
+
+  std::string mattr("-mattr=");
+  if(gotCpuFeatures){
+    for(StringMap<bool>::iterator I = Features.begin(),
+      E = Features.end(); I != E; ++I){
+      if(I->second){
+        std::string attr(I->first());
+        mattr+="+"+attr+",";
+      }
+    }
+    args.push_back(mattr.c_str());
+  }
+
+  args.push_back(0);  // terminator
+  cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]);
+
+  // Create the JIT
+  std::string ErrorMsg;
+
+  EngineBuilder builder(_normal_context->module());
+  builder.setMCPU(MCPU);
+  builder.setMAttrs(MAttrs);
+  builder.setJITMemoryManager(memory_manager());
+  builder.setEngineKind(EngineKind::JIT);
+  builder.setErrorStr(&ErrorMsg);
+  _execution_engine = builder.create();
+
+  if (!execution_engine()) {
+    if (!ErrorMsg.empty())
+      printf("Error while creating Shark JIT: %s\n",ErrorMsg.c_str());
+    else
+      printf("Unknown error while creating Shark JIT\n");
+    exit(1);
+  }
+
+  execution_engine()->addModule(
+    _native_context->module());
+#else
+  _execution_engine = ExecutionEngine::createJIT(
+    _normal_context->module_provider(),
+    NULL, memory_manager(), CodeGenOpt::Default);
+  execution_engine()->addModuleProvider(
+    _native_context->module_provider());
+#endif
+
+  // All done
+  mark_initialized();
+}
+
+void SharkCompiler::initialize() {
+  ShouldNotCallThis();
+}
+
+void SharkCompiler::compile_method(ciEnv*    env,
+                                   ciMethod* target,
+                                   int       entry_bci) {
+  assert(is_initialized(), "should be");
+  ResourceMark rm;
+  const char *name = methodname(
+    target->holder()->name()->as_utf8(), target->name()->as_utf8());
+
+  // Do the typeflow analysis
+  ciTypeFlow *flow;
+  if (entry_bci == InvocationEntryBci)
+    flow = target->get_flow_analysis();
+  else
+    flow = target->get_osr_flow_analysis(entry_bci);
+  if (flow->failing())
+    return;
+  if (SharkPrintTypeflowOf != NULL) {
+    if (!fnmatch(SharkPrintTypeflowOf, name, 0))
+      flow->print_on(tty);
+  }
+
+  // Create the recorders
+  Arena arena;
+  env->set_oop_recorder(new OopRecorder(&arena));
+  OopMapSet oopmaps;
+  env->set_debug_info(new DebugInformationRecorder(env->oop_recorder()));
+  env->debug_info()->set_oopmaps(&oopmaps);
+  env->set_dependencies(new Dependencies(env));
+
+  // Create the code buffer and builder
+  CodeBuffer hscb("Shark", 256 * K, 64 * K);
+  hscb.initialize_oop_recorder(env->oop_recorder());
+  MacroAssembler *masm = new MacroAssembler(&hscb);
+  SharkCodeBuffer cb(masm);
+  SharkBuilder builder(&cb);
+
+  // Emit the entry point
+  SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
+
+  // Build the LLVM IR for the method
+  Function *function = SharkFunction::build(env, &builder, flow, name);
+
+  // Generate native code.  It's unpleasant that we have to drop into
+  // the VM to do this -- it blocks safepoints -- but I can't see any
+  // other way to handle the locking.
+  {
+    ThreadInVMfromNative tiv(JavaThread::current());
+    generate_native_code(entry, function, name);
+  }
+
+  // Install the method into the VM
+  CodeOffsets offsets;
+  offsets.set_value(CodeOffsets::Deopt, 0);
+  offsets.set_value(CodeOffsets::Exceptions, 0);
+  offsets.set_value(CodeOffsets::Verified_Entry,
+                    target->is_static() ? 0 : wordSize);
+
+  ExceptionHandlerTable handler_table;
+  ImplicitExceptionTable inc_table;
+
+  env->register_method(target,
+                       entry_bci,
+                       &offsets,
+                       0,
+                       &hscb,
+                       0,
+                       &oopmaps,
+                       &handler_table,
+                       &inc_table,
+                       this,
+                       env->comp_level(),
+                       false,
+                       false);
+}
+
+nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm,
+                                                methodHandle    target,
+                                                BasicType*      arg_types,
+                                                BasicType       return_type) {
+  assert(is_initialized(), "should be");
+  ResourceMark rm;
+  const char *name = methodname(
+    target->klass_name()->as_utf8(), target->name()->as_utf8());
+
+  // Create the code buffer and builder
+  SharkCodeBuffer cb(masm);
+  SharkBuilder builder(&cb);
+
+  // Emit the entry point
+  SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
+
+  // Build the LLVM IR for the method
+  SharkNativeWrapper *wrapper = SharkNativeWrapper::build(
+    &builder, target, name, arg_types, return_type);
+
+  // Generate native code
+  generate_native_code(entry, wrapper->function(), name);
+
+  // Return the nmethod for installation in the VM
+  return nmethod::new_native_nmethod(target,
+                                     masm->code(),
+                                     0,
+                                     0,
+                                     wrapper->frame_size(),
+                                     wrapper->receiver_offset(),
+                                     wrapper->lock_offset(),
+                                     wrapper->oop_maps());
+}
+
+void SharkCompiler::generate_native_code(SharkEntry* entry,
+                                         Function*   function,
+                                         const char* name) {
+  // Print the LLVM bitcode, if requested
+  if (SharkPrintBitcodeOf != NULL) {
+    if (!fnmatch(SharkPrintBitcodeOf, name, 0))
+      function->dump();
+  }
+
+  // Compile to native code
+  address code = NULL;
+  context()->add_function(function);
+  {
+    MutexLocker locker(execution_engine_lock());
+    free_queued_methods();
+
+    if (SharkPrintAsmOf != NULL) {
+#if SHARK_LLVM_VERSION >= 27
+#ifndef NDEBUG
+      if (!fnmatch(SharkPrintAsmOf, name, 0)) {
+        llvm::SetCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit"));
+        llvm::DebugFlag = true;
+      }
+      else {
+        llvm::SetCurrentDebugType("");
+        llvm::DebugFlag = false;
+      }
+#endif // !NDEBUG
+#else
+      // NB you need to patch LLVM with http://tinyurl.com/yf3baln for this
+      std::vector<const char*> args;
+      args.push_back(""); // program name
+      if (!fnmatch(SharkPrintAsmOf, name, 0))
+        args.push_back("-debug-only=x86-emitter");
+      else
+        args.push_back("-debug-only=none");
+      args.push_back(0);  // terminator
+      cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]);
+#endif // SHARK_LLVM_VERSION
+    }
+    memory_manager()->set_entry_for_function(function, entry);
+    code = (address) execution_engine()->getPointerToFunction(function);
+  }
+  entry->set_entry_point(code);
+  entry->set_function(function);
+  entry->set_context(context());
+  address code_start = entry->code_start();
+  address code_limit = entry->code_limit();
+
+  // Register generated code for profiling, etc
+  if (JvmtiExport::should_post_dynamic_code_generated())
+    JvmtiExport::post_dynamic_code_generated(name, code_start, code_limit);
+
+  // Print debug information, if requested
+  if (SharkTraceInstalls) {
+    tty->print_cr(
+      " [%p-%p): %s (%d bytes code)",
+      code_start, code_limit, name, code_limit - code_start);
+  }
+}
+
+void SharkCompiler::free_compiled_method(address code) {
+  // This method may only be called when the VM is at a safepoint.
+  // All _thread_in_vm threads will be waiting for the safepoint to
+  // finish with the exception of the VM thread, so we can consider
+  // ourself the owner of the execution engine lock even though we
+  // can't actually acquire it at this time.
+  assert(Thread::current()->is_VM_thread(), "must be called by VM thread");
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+
+  SharkEntry *entry = (SharkEntry *) code;
+  entry->context()->push_to_free_queue(entry->function());
+}
+
+void SharkCompiler::free_queued_methods() {
+  // The free queue is protected by the execution engine lock
+  assert(execution_engine_lock()->owned_by_self(), "should be");
+
+  while (true) {
+    Function *function = context()->pop_from_free_queue();
+    if (function == NULL)
+      break;
+
+    execution_engine()->freeMachineCodeForFunction(function);
+    function->eraseFromParent();
+  }
+}
+
+const char* SharkCompiler::methodname(const char* klass, const char* method) {
+  char *buf = NEW_RESOURCE_ARRAY(char, strlen(klass) + 2 + strlen(method) + 1);
+
+  char *dst = buf;
+  for (const char *c = klass; *c; c++) {
+    if (*c == '/')
+      *(dst++) = '.';
+    else
+      *(dst++) = *c;
+  }
+  *(dst++) = ':';
+  *(dst++) = ':';
+  for (const char *c = method; *c; c++) {
+    *(dst++) = *c;
+  }
+  *(dst++) = '\0';
+  return buf;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCompiler.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkContext;
+
+class SharkCompiler : public AbstractCompiler {
+ public:
+  // Creation
+  SharkCompiler();
+
+  // Name of this compiler
+  const char *name()     { return "shark"; }
+
+  // Missing feature tests
+  bool supports_native() { return true; }
+  bool supports_osr()    { return true; }
+
+  // Customization
+  bool needs_adapters()  { return false; }
+  bool needs_stubs()     { return false; }
+
+  // Initialization
+  void initialize();
+
+  // Compile a normal (bytecode) method and install it in the VM
+  void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
+
+  // Generate a wrapper for a native (JNI) method
+  nmethod* generate_native_wrapper(MacroAssembler* masm,
+                                   methodHandle    target,
+                                   BasicType*      arg_types,
+                                   BasicType       return_type);
+
+  // Free compiled methods (and native wrappers)
+  void free_compiled_method(address code);
+
+  // Each thread generating IR needs its own context.  The normal
+  // context is used for bytecode methods, and is protected from
+  // multiple simultaneous accesses by being restricted to the
+  // compiler thread.  The native context is used for JNI methods,
+  // and is protected from multiple simultaneous accesses by the
+  // adapter handler library lock.
+ private:
+  SharkContext* _normal_context;
+  SharkContext* _native_context;
+
+ public:
+  SharkContext* context() const {
+    if (JavaThread::current()->is_Compiler_thread()) {
+      return _normal_context;
+    }
+    else {
+      assert(AdapterHandlerLibrary_lock->owned_by_self(), "should be");
+      return _native_context;
+    }
+  }
+
+  // The LLVM execution engine is the JIT we use to generate native
+  // code.  It is thread safe, but we need to protect it with a lock
+  // of our own because otherwise LLVM's lock and HotSpot's locks
+  // interleave and deadlock.  The SharkMemoryManager is not thread
+  // safe, and is protected by the same lock as the execution engine.
+ private:
+  Monitor*               _execution_engine_lock;
+  SharkMemoryManager*    _memory_manager;
+  llvm::ExecutionEngine* _execution_engine;
+
+ private:
+  Monitor* execution_engine_lock() const {
+    return _execution_engine_lock;
+  }
+  SharkMemoryManager* memory_manager() const {
+    assert(execution_engine_lock()->owned_by_self(), "should be");
+    return _memory_manager;
+  }
+  llvm::ExecutionEngine* execution_engine() const {
+    assert(execution_engine_lock()->owned_by_self(), "should be");
+    return _execution_engine;
+  }
+
+  // Global access
+ public:
+  static SharkCompiler* compiler() {
+    AbstractCompiler *compiler =
+      CompileBroker::compiler(CompLevel_fast_compile);
+    assert(compiler->is_shark() && compiler->is_initialized(), "should be");
+    return (SharkCompiler *) compiler;
+  }
+
+  // Helpers
+ private:
+  static const char* methodname(const char* klass, const char* method);
+  void generate_native_code(SharkEntry*     entry,
+                            llvm::Function* function,
+                            const char*     name);
+  void free_queued_methods();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkConstant.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkConstant.cpp.incl"
+
+using namespace llvm;
+
+SharkConstant* SharkConstant::for_ldc(ciBytecodeStream *iter) {
+  ciConstant constant = iter->get_constant();
+  ciType *type = NULL;
+  if (constant.basic_type() == T_OBJECT) {
+    ciEnv *env = ciEnv::current();
+    if (constant.as_object()->is_klass())
+      type = env->Class_klass();
+    else
+      type = env->String_klass();
+  }
+  return new SharkConstant(constant, type);
+}
+
+SharkConstant* SharkConstant::for_field(ciBytecodeStream *iter) {
+  bool will_link;
+  ciField *field = iter->get_field(will_link);
+  assert(will_link, "typeflow responsibility");
+
+  return new SharkConstant(field->constant_value(), field->type());
+}
+
+SharkConstant::SharkConstant(ciConstant constant, ciType *type) {
+  SharkValue *value = NULL;
+
+  switch (constant.basic_type()) {
+  case T_BOOLEAN:
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+  case T_INT:
+    value = SharkValue::jint_constant(constant.as_int());
+    break;
+
+  case T_LONG:
+    value = SharkValue::jlong_constant(constant.as_long());
+    break;
+
+  case T_FLOAT:
+    value = SharkValue::jfloat_constant(constant.as_float());
+    break;
+
+  case T_DOUBLE:
+    value = SharkValue::jdouble_constant(constant.as_double());
+    break;
+
+  case T_OBJECT:
+  case T_ARRAY:
+    break;
+
+  case T_ILLEGAL:
+    // out of memory
+    _is_loaded = false;
+    return;
+
+  default:
+    tty->print_cr("Unhandled type %s", type2name(constant.basic_type()));
+    ShouldNotReachHere();
+  }
+
+  // Handle primitive types.  We create SharkValues for these
+  // now; doing so doesn't emit any code, and it allows us to
+  // delegate a bunch of stuff to the SharkValue code.
+  if (value) {
+    _value       = value;
+    _is_loaded   = true;
+    _is_nonzero  = value->zero_checked();
+    _is_two_word = value->is_two_word();
+    return;
+  }
+
+  // Handle reference types.  This is tricky because some
+  // ciObjects are psuedo-objects that refer to oops which
+  // have yet to be created.  We need to spot the unloaded
+  // objects (which differ between ldc* and get*, thanks!)
+  ciObject *object = constant.as_object();
+  assert(type != NULL, "shouldn't be");
+  if (object->is_klass()) {
+    // The constant returned for a klass is the ciKlass
+    // for the entry, but we want the java_mirror.
+    ciKlass *klass = object->as_klass();
+    if (!klass->is_loaded()) {
+      _is_loaded = false;
+      return;
+    }
+    object = klass->java_mirror();
+  }
+  if (object->is_null_object() || !object->can_be_constant()) {
+    _is_loaded = false;
+    return;
+  }
+
+  _value       = NULL;
+  _object      = object;
+  _type        = type;
+  _is_loaded   = true;
+  _is_nonzero  = true;
+  _is_two_word = false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkConstant.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkConstant : public ResourceObj {
+ public:
+  static SharkConstant* for_ldc(ciBytecodeStream* iter);
+  static SharkConstant* for_field(ciBytecodeStream* iter);
+
+ private:
+  SharkConstant(ciConstant constant, ciType* type);
+
+ private:
+  SharkValue* _value;
+  ciObject*   _object;
+  ciType*     _type;
+  bool        _is_loaded;
+  bool        _is_nonzero;
+  bool        _is_two_word;
+
+ public:
+  bool is_loaded() const {
+    return _is_loaded;
+  }
+  bool is_nonzero() const {
+    assert(is_loaded(), "should be");
+    return _is_nonzero;
+  }
+  bool is_two_word() const {
+    assert(is_loaded(), "should be");
+    return _is_two_word;
+  }
+
+ public:
+  SharkValue* value(SharkBuilder* builder) {
+    assert(is_loaded(), "should be");
+    if (_value == NULL) {
+      _value = SharkValue::create_generic(
+        _type, builder->CreateInlineOop(_object), _is_nonzero);
+    }
+    return _value;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkContext.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkContext.cpp.incl"
+
+using namespace llvm;
+
+SharkContext::SharkContext(const char* name)
+  : LLVMContext(),
+    _free_queue(NULL) {
+  // Create a module to build our functions into
+  _module = new Module(name, *this);
+
+  // Create basic types
+  _void_type    = Type::getVoidTy(*this);
+  _bit_type     = Type::getInt1Ty(*this);
+  _jbyte_type   = Type::getInt8Ty(*this);
+  _jshort_type  = Type::getInt16Ty(*this);
+  _jint_type    = Type::getInt32Ty(*this);
+  _jlong_type   = Type::getInt64Ty(*this);
+  _jfloat_type  = Type::getFloatTy(*this);
+  _jdouble_type = Type::getDoubleTy(*this);
+
+  // Create compound types
+  _itableOffsetEntry_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), itableOffsetEntry::size() * wordSize));
+
+  _klass_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(Klass)));
+
+  _jniEnv_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(JNIEnv)));
+
+  _jniHandleBlock_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(JNIHandleBlock)));
+
+  _methodOop_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(methodOopDesc)));
+
+  _monitor_type = ArrayType::get(
+    jbyte_type(), frame::interpreter_frame_monitor_size() * wordSize);
+
+  _oop_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(oopDesc)));
+
+  _thread_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(JavaThread)));
+
+  _zeroStack_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(ZeroStack)));
+
+  std::vector<const Type*> params;
+  params.push_back(methodOop_type());
+  params.push_back(intptr_type());
+  params.push_back(thread_type());
+  _entry_point_type = FunctionType::get(jint_type(), params, false);
+
+  params.clear();
+  params.push_back(methodOop_type());
+  params.push_back(PointerType::getUnqual(jbyte_type()));
+  params.push_back(intptr_type());
+  params.push_back(thread_type());
+  _osr_entry_point_type = FunctionType::get(jint_type(), params, false);
+
+  // Create mappings
+  for (int i = 0; i < T_CONFLICT; i++) {
+    switch (i) {
+    case T_BOOLEAN:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jbyte_type();
+      break;
+
+    case T_BYTE:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jbyte_type();
+      break;
+
+    case T_CHAR:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jshort_type();
+      break;
+
+    case T_SHORT:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jshort_type();
+      break;
+
+    case T_INT:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jint_type();
+      break;
+
+    case T_LONG:
+      _to_stackType[i] = jlong_type();
+      _to_arrayType[i] = jlong_type();
+      break;
+
+    case T_FLOAT:
+      _to_stackType[i] = jfloat_type();
+      _to_arrayType[i] = jfloat_type();
+      break;
+
+    case T_DOUBLE:
+      _to_stackType[i] = jdouble_type();
+      _to_arrayType[i] = jdouble_type();
+      break;
+
+    case T_OBJECT:
+    case T_ARRAY:
+      _to_stackType[i] = oop_type();
+      _to_arrayType[i] = oop_type();
+      break;
+
+    case T_ADDRESS:
+      _to_stackType[i] = intptr_type();
+      _to_arrayType[i] = NULL;
+      break;
+
+    default:
+      _to_stackType[i] = NULL;
+      _to_arrayType[i] = NULL;
+    }
+  }
+}
+
+class SharkFreeQueueItem : public CHeapObj {
+ public:
+  SharkFreeQueueItem(llvm::Function* function, SharkFreeQueueItem *next)
+    : _function(function), _next(next) {}
+
+ private:
+  llvm::Function*     _function;
+  SharkFreeQueueItem* _next;
+
+ public:
+  llvm::Function* function() const {
+    return _function;
+  }
+  SharkFreeQueueItem* next() const {
+    return _next;
+  }
+};
+
+void SharkContext::push_to_free_queue(Function* function) {
+  _free_queue = new SharkFreeQueueItem(function, _free_queue);
+}
+
+Function* SharkContext::pop_from_free_queue() {
+  if (_free_queue == NULL)
+    return NULL;
+
+  SharkFreeQueueItem *item = _free_queue;
+  Function *function = item->function();
+  _free_queue = item->next();
+  delete item;
+  return function;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkContext.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 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.
+ *
+ */
+
+// The LLVMContext class allows multiple instances of LLVM to operate
+// independently of each other in a multithreaded context.  We extend
+// this here to store things in Shark that are LLVMContext-specific.
+
+class SharkFreeQueueItem;
+
+class SharkContext : public llvm::LLVMContext {
+ public:
+  SharkContext(const char* name);
+
+ private:
+  llvm::Module* _module;
+
+#if SHARK_LLVM_VERSION >= 27
+ public:
+#else
+ private:
+#endif
+  llvm::Module* module() const {
+    return _module;
+  }
+
+  // Get this thread's SharkContext
+ public:
+  static SharkContext& current() {
+    return *SharkCompiler::compiler()->context();
+  }
+
+  // Module accessors
+ public:
+#if SHARK_LLVM_VERSION < 27
+  llvm::ModuleProvider* module_provider() const {
+    return new llvm::ExistingModuleProvider(module());
+  }
+#endif
+  void add_function(llvm::Function* function) const {
+    module()->getFunctionList().push_back(function);
+  }
+  llvm::Constant* get_external(const char*               name,
+                               const llvm::FunctionType* sig) {
+    return module()->getOrInsertFunction(name, sig);
+  }
+
+  // Basic types
+ private:
+  const llvm::Type*        _void_type;
+  const llvm::IntegerType* _bit_type;
+  const llvm::IntegerType* _jbyte_type;
+  const llvm::IntegerType* _jshort_type;
+  const llvm::IntegerType* _jint_type;
+  const llvm::IntegerType* _jlong_type;
+  const llvm::Type*        _jfloat_type;
+  const llvm::Type*        _jdouble_type;
+
+ public:
+  const llvm::Type* void_type() const {
+    return _void_type;
+  }
+  const llvm::IntegerType* bit_type() const {
+    return _bit_type;
+  }
+  const llvm::IntegerType* jbyte_type() const {
+    return _jbyte_type;
+  }
+  const llvm::IntegerType* jshort_type() const {
+    return _jshort_type;
+  }
+  const llvm::IntegerType* jint_type() const {
+    return _jint_type;
+  }
+  const llvm::IntegerType* jlong_type() const {
+    return _jlong_type;
+  }
+  const llvm::Type* jfloat_type() const {
+    return _jfloat_type;
+  }
+  const llvm::Type* jdouble_type() const {
+    return _jdouble_type;
+  }
+  const llvm::IntegerType* intptr_type() const {
+    return LP64_ONLY(jlong_type()) NOT_LP64(jint_type());
+  }
+
+  // Compound types
+ private:
+  const llvm::PointerType*  _itableOffsetEntry_type;
+  const llvm::PointerType*  _jniEnv_type;
+  const llvm::PointerType*  _jniHandleBlock_type;
+  const llvm::PointerType*  _klass_type;
+  const llvm::PointerType*  _methodOop_type;
+  const llvm::ArrayType*    _monitor_type;
+  const llvm::PointerType*  _oop_type;
+  const llvm::PointerType*  _thread_type;
+  const llvm::PointerType*  _zeroStack_type;
+  const llvm::FunctionType* _entry_point_type;
+  const llvm::FunctionType* _osr_entry_point_type;
+
+ public:
+  const llvm::PointerType* itableOffsetEntry_type() const {
+    return _itableOffsetEntry_type;
+  }
+  const llvm::PointerType* jniEnv_type() const {
+    return _jniEnv_type;
+  }
+  const llvm::PointerType* jniHandleBlock_type() const {
+    return _jniHandleBlock_type;
+  }
+  const llvm::PointerType* klass_type() const {
+    return _klass_type;
+  }
+  const llvm::PointerType* methodOop_type() const {
+    return _methodOop_type;
+  }
+  const llvm::ArrayType* monitor_type() const {
+    return _monitor_type;
+  }
+  const llvm::PointerType* oop_type() const {
+    return _oop_type;
+  }
+  const llvm::PointerType* thread_type() const {
+    return _thread_type;
+  }
+  const llvm::PointerType* zeroStack_type() const {
+    return _zeroStack_type;
+  }
+  const llvm::FunctionType* entry_point_type() const {
+    return _entry_point_type;
+  }
+  const llvm::FunctionType* osr_entry_point_type() const {
+    return _osr_entry_point_type;
+  }
+
+  // Mappings
+ private:
+  const llvm::Type* _to_stackType[T_CONFLICT];
+  const llvm::Type* _to_arrayType[T_CONFLICT];
+
+ private:
+  const llvm::Type* map_type(const llvm::Type* const* table,
+                             BasicType                type) const {
+    assert(type >= 0 && type < T_CONFLICT, "unhandled type");
+    const llvm::Type* result = table[type];
+    assert(type != NULL, "unhandled type");
+    return result;
+  }
+
+ public:
+  const llvm::Type* to_stackType(BasicType type) const {
+    return map_type(_to_stackType, type);
+  }
+  const llvm::Type* to_arrayType(BasicType type) const {
+    return map_type(_to_arrayType, type);
+  }
+
+  // Functions queued for freeing
+ private:
+  SharkFreeQueueItem* _free_queue;
+
+ public:
+  void push_to_free_queue(llvm::Function* function);
+  llvm::Function* pop_from_free_queue();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkEntry.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkContext;
+
+class SharkEntry : public ZeroEntry {
+ private:
+  address         _code_limit;
+  SharkContext*   _context;
+  llvm::Function* _function;
+
+ public:
+  address code_start() const {
+    return entry_point();
+  }
+  address code_limit() const {
+    return _code_limit;
+  }
+  SharkContext* context() const {
+    return _context;
+  }
+  llvm::Function* function() const {
+    return _function;
+  }
+
+ public:
+  void set_code_limit(address code_limit) {
+    _code_limit = code_limit;
+  }
+  void set_context(SharkContext* context) {
+    _context = context;
+  }
+  void set_function(llvm::Function* function) {
+    _function = function;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkFunction.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkFunction.cpp.incl"
+
+using namespace llvm;
+
+void SharkFunction::initialize(const char *name) {
+  // Create the function
+  _function = Function::Create(
+    entry_point_type(),
+    GlobalVariable::InternalLinkage,
+    name);
+
+  // Get our arguments
+  Function::arg_iterator ai = function()->arg_begin();
+  Argument *method = ai++;
+  method->setName("method");
+  Argument *osr_buf = NULL;
+  if (is_osr()) {
+    osr_buf = ai++;
+    osr_buf->setName("osr_buf");
+  }
+  Argument *base_pc = ai++;
+  base_pc->setName("base_pc");
+  code_buffer()->set_base_pc(base_pc);
+  Argument *thread = ai++;
+  thread->setName("thread");
+  set_thread(thread);
+
+  // Create the list of blocks
+  set_block_insertion_point(NULL);
+  _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count());
+  for (int i = 0; i < block_count(); i++) {
+    ciTypeFlow::Block *b = flow()->pre_order_at(i);
+
+    // Work around a bug in pre_order_at() that does not return
+    // the correct pre-ordering.  If pre_order_at() were correct
+    // this line could simply be:
+    // _blocks[i] = new SharkTopLevelBlock(this, b);
+    _blocks[b->pre_order()] = new SharkTopLevelBlock(this, b);
+  }
+
+  // Walk the tree from the start block to determine which
+  // blocks are entered and which blocks require phis
+  SharkTopLevelBlock *start_block = block(flow()->start_block_num());
+  assert(start_block->start() == flow()->start_bci(), "blocks out of order");
+  start_block->enter();
+
+  // Initialize all entered blocks
+  for (int i = 0; i < block_count(); i++) {
+    if (block(i)->entered())
+      block(i)->initialize();
+  }
+
+  // Create and push our stack frame
+  set_block_insertion_point(&function()->front());
+  builder()->SetInsertPoint(CreateBlock());
+  _stack = SharkStack::CreateBuildAndPushFrame(this, method);
+
+  // Create the entry state
+  SharkState *entry_state;
+  if (is_osr()) {
+    entry_state = new SharkOSREntryState(start_block, method, osr_buf);
+
+    // Free the OSR buffer
+    builder()->CreateCall(builder()->osr_migration_end(), osr_buf);
+  }
+  else {
+    entry_state = new SharkNormalEntryState(start_block, method);
+
+    // Lock if necessary
+    if (is_synchronized()) {
+      SharkTopLevelBlock *locker =
+        new SharkTopLevelBlock(this, start_block->ciblock());
+      locker->add_incoming(entry_state);
+
+      set_block_insertion_point(start_block->entry_block());
+      locker->acquire_method_lock();
+
+      entry_state = locker->current_state();
+    }
+  }
+
+  // Transition into the method proper
+  start_block->add_incoming(entry_state);
+  builder()->CreateBr(start_block->entry_block());
+
+  // Parse the blocks
+  for (int i = 0; i < block_count(); i++) {
+    if (!block(i)->entered())
+      continue;
+
+    if (i + 1 < block_count())
+      set_block_insertion_point(block(i + 1)->entry_block());
+    else
+      set_block_insertion_point(NULL);
+
+    block(i)->emit_IR();
+  }
+  do_deferred_zero_checks();
+}
+
+class DeferredZeroCheck : public SharkTargetInvariants {
+ public:
+  DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value)
+    : SharkTargetInvariants(block),
+      _block(block),
+      _value(value),
+      _bci(block->bci()),
+      _state(block->current_state()->copy()),
+      _check_block(builder()->GetInsertBlock()),
+      _continue_block(function()->CreateBlock("not_zero")) {
+    builder()->SetInsertPoint(continue_block());
+  }
+
+ private:
+  SharkTopLevelBlock* _block;
+  SharkValue*         _value;
+  int                 _bci;
+  SharkState*         _state;
+  BasicBlock*         _check_block;
+  BasicBlock*         _continue_block;
+
+ public:
+  SharkTopLevelBlock* block() const {
+    return _block;
+  }
+  SharkValue* value() const {
+    return _value;
+  }
+  int bci() const {
+    return _bci;
+  }
+  SharkState* state() const {
+    return _state;
+  }
+  BasicBlock* check_block() const {
+    return _check_block;
+  }
+  BasicBlock* continue_block() const {
+    return _continue_block;
+  }
+
+ public:
+  SharkFunction* function() const {
+    return block()->function();
+  }
+
+ public:
+  void process() const {
+    builder()->SetInsertPoint(check_block());
+    block()->do_deferred_zero_check(value(), bci(), state(), continue_block());
+  }
+};
+
+void SharkFunction::add_deferred_zero_check(SharkTopLevelBlock* block,
+                                            SharkValue*         value) {
+  deferred_zero_checks()->append(new DeferredZeroCheck(block, value));
+}
+
+void SharkFunction::do_deferred_zero_checks() {
+  for (int i = 0; i < deferred_zero_checks()->length(); i++)
+    deferred_zero_checks()->at(i)->process();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkFunction.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkTopLevelBlock;
+class DeferredZeroCheck;
+
+class SharkFunction : public SharkTargetInvariants {
+ friend class SharkStackWithNormalFrame;
+
+ public:
+  static llvm::Function* build(ciEnv*        env,
+                               SharkBuilder* builder,
+                               ciTypeFlow*   flow,
+                               const char*   name) {
+    SharkFunction function(env, builder, flow, name);
+    return function.function();
+  }
+
+ private:
+  SharkFunction(ciEnv*        env,
+                SharkBuilder* builder,
+                ciTypeFlow*   flow,
+                const char*   name)
+    : SharkTargetInvariants(env, builder, flow) { initialize(name); }
+
+ private:
+  void initialize(const char* name);
+
+ private:
+  llvm::Function*                   _function;
+  SharkTopLevelBlock**              _blocks;
+  GrowableArray<DeferredZeroCheck*> _deferred_zero_checks;
+  SharkStack*                       _stack;
+
+ public:
+  llvm::Function* function() const {
+    return _function;
+  }
+  int block_count() const {
+    return flow()->block_count();
+  }
+  SharkTopLevelBlock* block(int i) const {
+    assert(i < block_count(), "should be");
+    return _blocks[i];
+  }
+  GrowableArray<DeferredZeroCheck*>* deferred_zero_checks() {
+    return &_deferred_zero_checks;
+  }
+  SharkStack* stack() const {
+    return _stack;
+  }
+
+  // On-stack replacement
+ private:
+  bool is_osr() const {
+    return flow()->is_osr_flow();
+  }
+  const llvm::FunctionType* entry_point_type() const {
+    if (is_osr())
+      return SharkType::osr_entry_point_type();
+    else
+      return SharkType::entry_point_type();
+  }
+
+  // Block management
+ private:
+  llvm::BasicBlock* _block_insertion_point;
+
+  void set_block_insertion_point(llvm::BasicBlock* block_insertion_point) {
+    _block_insertion_point = block_insertion_point;
+  }
+  llvm::BasicBlock* block_insertion_point() const {
+    return _block_insertion_point;
+  }
+
+ public:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const {
+    return llvm::BasicBlock::Create(
+      SharkContext::current(), name, function(), block_insertion_point());
+  }
+
+  // Deferred zero checks
+ public:
+  void add_deferred_zero_check(SharkTopLevelBlock* block,
+                               SharkValue*         value);
+
+ private:
+  void do_deferred_zero_checks();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInliner.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,749 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkInliner.cpp.incl"
+
+using namespace llvm;
+
+class SharkInlineBlock : public SharkBlock {
+ public:
+  SharkInlineBlock(ciMethod* target, SharkState* state)
+    : SharkBlock(state, target),
+      _outer_state(state),
+      _entry_state(new SharkState(this)) {
+    for (int i = target->max_locals() - 1; i >= 0; i--) {
+      SharkValue *value = NULL;
+      if (i < target->arg_size())
+        value = outer_state()->pop();
+      entry_state()->set_local(i, value);
+    }
+  }
+
+ private:
+  SharkState* _outer_state;
+  SharkState* _entry_state;
+
+ private:
+  SharkState* outer_state() {
+    return _outer_state;
+  }
+  SharkState* entry_state() {
+    return _entry_state;
+  }
+
+ public:
+  void emit_IR() {
+    parse_bytecode(0, target()->code_size());
+  }
+
+ private:
+  void do_return(BasicType type) {
+    if (type != T_VOID) {
+      SharkValue *result = pop_result(type);
+      outer_state()->push(result);
+      if (result->is_two_word())
+        outer_state()->push(NULL);
+    }
+  }
+};
+
+class SharkInlinerHelper : public StackObj {
+ public:
+  SharkInlinerHelper(ciMethod* target, SharkState* entry_state)
+    : _target(target),
+      _entry_state(entry_state),
+      _iter(target) {}
+
+ private:
+  ciBytecodeStream _iter;
+  SharkState*      _entry_state;
+  ciMethod*        _target;
+
+ public:
+  ciBytecodeStream* iter() {
+    return &_iter;
+  }
+  SharkState* entry_state() const {
+    return _entry_state;
+  }
+  ciMethod* target() const {
+    return _target;
+  }
+
+ public:
+  Bytecodes::Code bc() {
+    return iter()->cur_bc();
+  }
+  int max_locals() const {
+    return target()->max_locals();
+  }
+  int max_stack() const {
+    return target()->max_stack();
+  }
+
+  // Inlinability check
+ public:
+  bool is_inlinable();
+
+ private:
+  void initialize_for_check();
+
+  bool do_getstatic() {
+    return do_field_access(true, false);
+  }
+  bool do_getfield() {
+    return do_field_access(true, true);
+  }
+  bool do_putfield() {
+    return do_field_access(false, true);
+  }
+  bool do_field_access(bool is_get, bool is_field);
+
+  // Local variables for inlinability check
+ private:
+  bool* _locals;
+
+ public:
+  bool* local_addr(int index) const {
+    assert(index >= 0 && index < max_locals(), "bad local variable index");
+    return &_locals[index];
+  }
+  bool local(int index) const {
+    return *local_addr(index);
+  }
+  void set_local(int index, bool value) {
+    *local_addr(index) = value;
+  }
+
+  // Expression stack for inlinability check
+ private:
+  bool* _stack;
+  bool* _sp;
+
+ public:
+  int stack_depth() const {
+    return _sp - _stack;
+  }
+  bool* stack_addr(int slot) const {
+    assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
+    return &_sp[-(slot + 1)];
+  }
+  void push(bool value) {
+    assert(stack_depth() < max_stack(), "stack overrun");
+    *(_sp++) = value;
+  }
+  bool pop() {
+    assert(stack_depth() > 0, "stack underrun");
+    return *(--_sp);
+  }
+
+  // Methods for two-word locals
+ public:
+  void push_pair_local(int index) {
+    push(local(index));
+    push(local(index + 1));
+  }
+  void pop_pair_local(int index) {
+    set_local(index + 1, pop());
+    set_local(index, pop());
+  }
+
+  // Code generation
+ public:
+  void do_inline() {
+    (new SharkInlineBlock(target(), entry_state()))->emit_IR();
+  }
+};
+
+// Quick checks so we can bail out before doing too much
+bool SharkInliner::may_be_inlinable(ciMethod *target) {
+  // We can't inline native methods
+  if (target->is_native())
+    return false;
+
+  // Not much point inlining abstract ones, and in any
+  // case we'd need a stack frame to throw the exception
+  if (target->is_abstract())
+    return false;
+
+  // Don't inline anything huge
+  if (target->code_size() > SharkMaxInlineSize)
+    return false;
+
+  // Monitors aren't allowed without a frame to put them in
+  if (target->is_synchronized() || target->has_monitor_bytecodes())
+    return false;
+
+  // We don't do control flow
+  if (target->has_exception_handlers() || target->has_jsrs())
+    return false;
+
+  // Don't try to inline constructors, as they must
+  // eventually call Object.<init> which we can't inline.
+  // Note that this catches <clinit> too, but why would
+  // we be compiling that?
+  if (target->is_initializer())
+    return false;
+
+  // Mustn't inline Object.<init>
+  // Should be caught by the above, but just in case...
+  if (target->intrinsic_id() == vmIntrinsics::_Object_init)
+    return false;
+
+  return true;
+}
+
+// Full-on detailed check, for methods that pass the quick checks
+// Inlined methods have no stack frame, so we can't do anything
+// that would require one.  This means no safepoints (and hence
+// no loops) and no VM calls.  No VM calls means, amongst other
+// things, that no exceptions can be created, which means no null
+// checks or divide-by-zero checks are allowed.  The lack of null
+// checks in particular would eliminate practically everything,
+// but we can get around that restriction by relying on the zero-
+// check eliminator to strip the checks.  To do that, we need to
+// walk through the method, tracking which values are and are not
+// zero-checked.
+bool SharkInlinerHelper::is_inlinable() {
+  ResourceMark rm;
+  initialize_for_check();
+
+  SharkConstant *sc;
+  bool a, b, c, d;
+
+  iter()->reset_to_bci(0);
+  while (iter()->next() != ciBytecodeStream::EOBC()) {
+    switch (bc()) {
+    case Bytecodes::_nop:
+      break;
+
+    case Bytecodes::_aconst_null:
+      push(false);
+      break;
+
+    case Bytecodes::_iconst_0:
+      push(false);
+      break;
+    case Bytecodes::_iconst_m1:
+    case Bytecodes::_iconst_1:
+    case Bytecodes::_iconst_2:
+    case Bytecodes::_iconst_3:
+    case Bytecodes::_iconst_4:
+    case Bytecodes::_iconst_5:
+      push(true);
+      break;
+
+    case Bytecodes::_lconst_0:
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_lconst_1:
+      push(true);
+      push(false);
+      break;
+
+    case Bytecodes::_fconst_0:
+    case Bytecodes::_fconst_1:
+    case Bytecodes::_fconst_2:
+      push(false);
+      break;
+
+    case Bytecodes::_dconst_0:
+    case Bytecodes::_dconst_1:
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_bipush:
+      push(iter()->get_constant_u1() != 0);
+      break;
+    case Bytecodes::_sipush:
+      push(iter()->get_constant_u2() != 0);
+      break;
+
+    case Bytecodes::_ldc:
+    case Bytecodes::_ldc_w:
+    case Bytecodes::_ldc2_w:
+      sc = SharkConstant::for_ldc(iter());
+      if (!sc->is_loaded())
+        return false;
+      push(sc->is_nonzero());
+      if (sc->is_two_word())
+        push(false);
+      break;
+
+    case Bytecodes::_iload_0:
+    case Bytecodes::_fload_0:
+    case Bytecodes::_aload_0:
+      push(local(0));
+      break;
+    case Bytecodes::_lload_0:
+    case Bytecodes::_dload_0:
+      push_pair_local(0);
+      break;
+
+    case Bytecodes::_iload_1:
+    case Bytecodes::_fload_1:
+    case Bytecodes::_aload_1:
+      push(local(1));
+      break;
+    case Bytecodes::_lload_1:
+    case Bytecodes::_dload_1:
+      push_pair_local(1);
+      break;
+
+    case Bytecodes::_iload_2:
+    case Bytecodes::_fload_2:
+    case Bytecodes::_aload_2:
+      push(local(2));
+      break;
+    case Bytecodes::_lload_2:
+    case Bytecodes::_dload_2:
+      push_pair_local(2);
+      break;
+
+    case Bytecodes::_iload_3:
+    case Bytecodes::_fload_3:
+    case Bytecodes::_aload_3:
+      push(local(3));
+      break;
+    case Bytecodes::_lload_3:
+    case Bytecodes::_dload_3:
+      push_pair_local(3);
+      break;
+
+    case Bytecodes::_iload:
+    case Bytecodes::_fload:
+    case Bytecodes::_aload:
+      push(local(iter()->get_index()));
+      break;
+    case Bytecodes::_lload:
+    case Bytecodes::_dload:
+      push_pair_local(iter()->get_index());
+      break;
+
+    case Bytecodes::_istore_0:
+    case Bytecodes::_fstore_0:
+    case Bytecodes::_astore_0:
+      set_local(0, pop());
+      break;
+    case Bytecodes::_lstore_0:
+    case Bytecodes::_dstore_0:
+      pop_pair_local(0);
+      break;
+
+    case Bytecodes::_istore_1:
+    case Bytecodes::_fstore_1:
+    case Bytecodes::_astore_1:
+      set_local(1, pop());
+      break;
+    case Bytecodes::_lstore_1:
+    case Bytecodes::_dstore_1:
+      pop_pair_local(1);
+      break;
+
+    case Bytecodes::_istore_2:
+    case Bytecodes::_fstore_2:
+    case Bytecodes::_astore_2:
+      set_local(2, pop());
+      break;
+    case Bytecodes::_lstore_2:
+    case Bytecodes::_dstore_2:
+      pop_pair_local(2);
+      break;
+
+    case Bytecodes::_istore_3:
+    case Bytecodes::_fstore_3:
+    case Bytecodes::_astore_3:
+      set_local(3, pop());
+      break;
+    case Bytecodes::_lstore_3:
+    case Bytecodes::_dstore_3:
+      pop_pair_local(3);
+      break;
+
+    case Bytecodes::_istore:
+    case Bytecodes::_fstore:
+    case Bytecodes::_astore:
+      set_local(iter()->get_index(), pop());
+      break;
+    case Bytecodes::_lstore:
+    case Bytecodes::_dstore:
+      pop_pair_local(iter()->get_index());
+      break;
+
+    case Bytecodes::_pop:
+      pop();
+      break;
+    case Bytecodes::_pop2:
+      pop();
+      pop();
+      break;
+    case Bytecodes::_swap:
+      a = pop();
+      b = pop();
+      push(a);
+      push(b);
+      break;
+    case Bytecodes::_dup:
+      a = pop();
+      push(a);
+      push(a);
+      break;
+    case Bytecodes::_dup_x1:
+      a = pop();
+      b = pop();
+      push(a);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup_x2:
+      a = pop();
+      b = pop();
+      c = pop();
+      push(a);
+      push(c);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup2:
+      a = pop();
+      b = pop();
+      push(b);
+      push(a);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup2_x1:
+      a = pop();
+      b = pop();
+      c = pop();
+      push(b);
+      push(a);
+      push(c);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup2_x2:
+      a = pop();
+      b = pop();
+      c = pop();
+      d = pop();
+      push(b);
+      push(a);
+      push(d);
+      push(c);
+      push(b);
+      push(a);
+      break;
+
+    case Bytecodes::_getfield:
+      if (!do_getfield())
+        return false;
+      break;
+    case Bytecodes::_getstatic:
+      if (!do_getstatic())
+        return false;
+      break;
+    case Bytecodes::_putfield:
+      if (!do_putfield())
+        return false;
+      break;
+
+    case Bytecodes::_iadd:
+    case Bytecodes::_isub:
+    case Bytecodes::_imul:
+    case Bytecodes::_iand:
+    case Bytecodes::_ixor:
+    case Bytecodes::_ishl:
+    case Bytecodes::_ishr:
+    case Bytecodes::_iushr:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_ior:
+      a = pop();
+      b = pop();
+      push(a && b);
+      break;
+    case Bytecodes::_idiv:
+    case Bytecodes::_irem:
+      if (!pop())
+        return false;
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_ineg:
+      break;
+
+    case Bytecodes::_ladd:
+    case Bytecodes::_lsub:
+    case Bytecodes::_lmul:
+    case Bytecodes::_land:
+    case Bytecodes::_lxor:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_lor:
+      a = pop();
+      b = pop();
+      push(a && b);
+      break;
+    case Bytecodes::_ldiv:
+    case Bytecodes::_lrem:
+      pop();
+      if (!pop())
+        return false;
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_lneg:
+      break;
+    case Bytecodes::_lshl:
+    case Bytecodes::_lshr:
+    case Bytecodes::_lushr:
+      pop();
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_fadd:
+    case Bytecodes::_fsub:
+    case Bytecodes::_fmul:
+    case Bytecodes::_fdiv:
+    case Bytecodes::_frem:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_fneg:
+      break;
+
+    case Bytecodes::_dadd:
+    case Bytecodes::_dsub:
+    case Bytecodes::_dmul:
+    case Bytecodes::_ddiv:
+    case Bytecodes::_drem:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_dneg:
+      break;
+
+    case Bytecodes::_iinc:
+      set_local(iter()->get_index(), false);
+      break;
+
+    case Bytecodes::_lcmp:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_fcmpl:
+    case Bytecodes::_fcmpg:
+      pop();
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_dcmpl:
+    case Bytecodes::_dcmpg:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_i2l:
+      push(false);
+      break;
+    case Bytecodes::_i2f:
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_i2d:
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_l2i:
+    case Bytecodes::_l2f:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_l2d:
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_f2i:
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_f2l:
+    case Bytecodes::_f2d:
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_d2i:
+    case Bytecodes::_d2f:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_d2l:
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_i2b:
+    case Bytecodes::_i2c:
+    case Bytecodes::_i2s:
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_return:
+    case Bytecodes::_ireturn:
+    case Bytecodes::_lreturn:
+    case Bytecodes::_freturn:
+    case Bytecodes::_dreturn:
+    case Bytecodes::_areturn:
+      break;
+
+    default:
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void SharkInlinerHelper::initialize_for_check() {
+  _locals = NEW_RESOURCE_ARRAY(bool, max_locals());
+  _stack = NEW_RESOURCE_ARRAY(bool, max_stack());
+
+  memset(_locals, 0, max_locals() * sizeof(bool));
+  for (int i = 0; i < target()->arg_size(); i++) {
+    SharkValue *arg = entry_state()->stack(target()->arg_size() - 1 - i);
+    if (arg && arg->zero_checked())
+      set_local(i, true);
+  }
+
+  _sp = _stack;
+}
+
+bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) {
+  assert(is_get || is_field, "can't inline putstatic");
+
+  // If the holder isn't linked then there isn't a lot we can do
+  if (!target()->holder()->is_linked())
+    return false;
+
+  // Get the field
+  bool will_link;
+  ciField *field = iter()->get_field(will_link);
+  if (!will_link)
+    return false;
+
+  // If the field is mismatched then an exception needs throwing
+  if (is_field == field->is_static())
+    return false;
+
+  // Pop the value off the stack if necessary
+  if (!is_get) {
+    pop();
+    if (field->type()->is_two_word())
+      pop();
+  }
+
+  // Pop and null-check the receiver if necessary
+  if (is_field) {
+    if (!pop())
+      return false;
+  }
+
+  // Push the result if necessary
+  if (is_get) {
+    bool result_pushed = false;
+    if (field->is_constant()) {
+      SharkConstant *sc = SharkConstant::for_field(iter());
+      if (sc->is_loaded()) {
+        push(sc->is_nonzero());
+        result_pushed = true;
+      }
+    }
+
+    if (!result_pushed)
+      push(false);
+
+    if (field->type()->is_two_word())
+      push(false);
+  }
+
+  return true;
+}
+
+bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) {
+  if (SharkIntrinsics::is_intrinsic(target)) {
+    SharkIntrinsics::inline_intrinsic(target, state);
+    return true;
+  }
+
+  if (may_be_inlinable(target)) {
+    SharkInlinerHelper inliner(target, state);
+    if (inliner.is_inlinable()) {
+      inliner.do_inline();
+      return true;
+    }
+  }
+  return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInliner.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkInliner : public AllStatic {
+ public:
+  static bool attempt_inline(ciMethod* target, SharkState* state);
+
+ private:
+  static bool may_be_inlinable(ciMethod* target);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkIntrinsics.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkIntrinsics.cpp.incl"
+
+using namespace llvm;
+
+bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
+  switch (target->intrinsic_id()) {
+  case vmIntrinsics::_none:
+    return false;
+
+    // java.lang.Math
+  case vmIntrinsics::_min:
+  case vmIntrinsics::_max:
+  case vmIntrinsics::_dabs:
+  case vmIntrinsics::_dsin:
+  case vmIntrinsics::_dcos:
+  case vmIntrinsics::_dtan:
+  case vmIntrinsics::_datan2:
+  case vmIntrinsics::_dsqrt:
+  case vmIntrinsics::_dlog:
+  case vmIntrinsics::_dlog10:
+  case vmIntrinsics::_dpow:
+  case vmIntrinsics::_dexp:
+    return true;
+
+    // java.lang.Object
+  case vmIntrinsics::_getClass:
+    return true;
+
+    // java.lang.System
+  case vmIntrinsics::_currentTimeMillis:
+    return true;
+
+    // java.lang.Thread
+  case vmIntrinsics::_currentThread:
+    return true;
+
+    // sun.misc.Unsafe
+  case vmIntrinsics::_compareAndSwapInt:
+    return true;
+
+  default:
+    if (SharkPerformanceWarnings) {
+      warning(
+        "unhandled intrinsic vmIntrinsic::%s",
+        vmIntrinsics::name_at(target->intrinsic_id()));
+    }
+  }
+  return false;
+}
+
+void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) {
+  SharkIntrinsics intrinsic(state, target);
+  intrinsic.do_intrinsic();
+}
+
+void SharkIntrinsics::do_intrinsic() {
+  switch (target()->intrinsic_id()) {
+    // java.lang.Math
+  case vmIntrinsics::_min:
+    do_Math_minmax(llvm::ICmpInst::ICMP_SLE);
+    break;
+  case vmIntrinsics::_max:
+    do_Math_minmax(llvm::ICmpInst::ICMP_SGE);
+    break;
+  case vmIntrinsics::_dabs:
+    do_Math_1to1(builder()->fabs());
+    break;
+  case vmIntrinsics::_dsin:
+    do_Math_1to1(builder()->sin());
+    break;
+  case vmIntrinsics::_dcos:
+    do_Math_1to1(builder()->cos());
+    break;
+  case vmIntrinsics::_dtan:
+    do_Math_1to1(builder()->tan());
+    break;
+  case vmIntrinsics::_datan2:
+    do_Math_2to1(builder()->atan2());
+    break;
+  case vmIntrinsics::_dsqrt:
+    do_Math_1to1(builder()->sqrt());
+    break;
+  case vmIntrinsics::_dlog:
+    do_Math_1to1(builder()->log());
+    break;
+  case vmIntrinsics::_dlog10:
+    do_Math_1to1(builder()->log10());
+    break;
+  case vmIntrinsics::_dpow:
+    do_Math_2to1(builder()->pow());
+    break;
+  case vmIntrinsics::_dexp:
+    do_Math_1to1(builder()->exp());
+    break;
+
+    // java.lang.Object
+  case vmIntrinsics::_getClass:
+    do_Object_getClass();
+    break;
+
+    // java.lang.System
+  case vmIntrinsics::_currentTimeMillis:
+    do_System_currentTimeMillis();
+    break;
+
+    // java.lang.Thread
+  case vmIntrinsics::_currentThread:
+    do_Thread_currentThread();
+    break;
+
+    // sun.misc.Unsafe
+  case vmIntrinsics::_compareAndSwapInt:
+    do_Unsafe_compareAndSwapInt();
+    break;
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) {
+  // Pop the arguments
+  SharkValue *sb = state()->pop();
+  SharkValue *sa = state()->pop();
+  Value *a = sa->jint_value();
+  Value *b = sb->jint_value();
+
+  // Perform the test
+  BasicBlock *ip       = builder()->GetBlockInsertionPoint();
+  BasicBlock *return_a = builder()->CreateBlock(ip, "return_a");
+  BasicBlock *return_b = builder()->CreateBlock(ip, "return_b");
+  BasicBlock *done     = builder()->CreateBlock(ip, "done");
+
+  builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b);
+
+  builder()->SetInsertPoint(return_a);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(return_b);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *phi = builder()->CreatePHI(a->getType(), "result");
+  phi->addIncoming(a, return_a);
+  phi->addIncoming(b, return_b);
+
+  // Push the result
+  state()->push(
+    SharkValue::create_jint(
+      phi,
+      sa->zero_checked() && sb->zero_checked()));
+}
+
+void SharkIntrinsics::do_Math_1to1(Value *function) {
+  SharkValue *empty = state()->pop();
+  assert(empty == NULL, "should be");
+  state()->push(
+    SharkValue::create_jdouble(
+      builder()->CreateCall(
+        function, state()->pop()->jdouble_value())));
+  state()->push(NULL);
+}
+
+void SharkIntrinsics::do_Math_2to1(Value *function) {
+  SharkValue *empty = state()->pop();
+  assert(empty == NULL, "should be");
+  Value *y = state()->pop()->jdouble_value();
+  empty = state()->pop();
+  assert(empty == NULL, "should be");
+  Value *x = state()->pop()->jdouble_value();
+
+  state()->push(
+    SharkValue::create_jdouble(
+      builder()->CreateCall2(function, x, y)));
+  state()->push(NULL);
+}
+
+void SharkIntrinsics::do_Object_getClass() {
+  Value *klass = builder()->CreateValueOfStructEntry(
+    state()->pop()->jobject_value(),
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "klass");
+
+  Value *klass_part = builder()->CreateAddressOfStructEntry(
+    klass,
+    in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()),
+    SharkType::klass_type(),
+    "klass_part");
+
+  state()->push(
+    SharkValue::create_jobject(
+      builder()->CreateValueOfStructEntry(
+        klass_part,
+        in_ByteSize(Klass::java_mirror_offset_in_bytes()),
+        SharkType::oop_type(),
+        "java_mirror"),
+      true));
+}
+
+void SharkIntrinsics::do_System_currentTimeMillis() {
+  state()->push(
+    SharkValue::create_jlong(
+      builder()->CreateCall(builder()->current_time_millis()),
+      false));
+  state()->push(NULL);
+}
+
+void SharkIntrinsics::do_Thread_currentThread() {
+  state()->push(
+    SharkValue::create_jobject(
+      builder()->CreateValueOfStructEntry(
+        thread(), JavaThread::threadObj_offset(),
+        SharkType::oop_type(),
+        "threadObj"),
+      true));
+}
+
+void SharkIntrinsics::do_Unsafe_compareAndSwapInt() {
+  // Pop the arguments
+  Value *x      = state()->pop()->jint_value();
+  Value *e      = state()->pop()->jint_value();
+  SharkValue *empty = state()->pop();
+  assert(empty == NULL, "should be");
+  Value *offset = state()->pop()->jlong_value();
+  Value *object = state()->pop()->jobject_value();
+  Value *unsafe = state()->pop()->jobject_value();
+
+  // Convert the offset
+  offset = builder()->CreateCall(
+    builder()->unsafe_field_offset_to_byte_offset(),
+    offset);
+
+  // Locate the field
+  Value *addr = builder()->CreateIntToPtr(
+    builder()->CreateAdd(
+      builder()->CreatePtrToInt(object, SharkType::intptr_type()),
+      builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),
+    PointerType::getUnqual(SharkType::jint_type()),
+    "addr");
+
+  // Perform the operation
+  Value *result = builder()->CreateCmpxchgInt(x, addr, e);
+
+  // Push the result
+  state()->push(
+    SharkValue::create_jint(
+      builder()->CreateIntCast(
+        builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),
+      false));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkIntrinsics.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkIntrinsics : public SharkTargetInvariants {
+ public:
+  static bool is_intrinsic(ciMethod* target);
+  static void inline_intrinsic(ciMethod* target, SharkState* state);
+
+ private:
+  SharkIntrinsics(SharkState* state, ciMethod* target)
+    : SharkTargetInvariants(state, target), _state(state) {}
+
+ private:
+  SharkState* _state;
+
+ private:
+  SharkState* state() const {
+    return _state;
+  }
+
+ private:
+  void do_intrinsic();
+
+ private:
+  void do_Math_minmax(llvm::ICmpInst::Predicate p);
+  void do_Math_1to1(llvm::Value* function);
+  void do_Math_2to1(llvm::Value* function);
+  void do_Object_getClass();
+  void do_System_currentTimeMillis();
+  void do_Thread_currentThread();
+  void do_Unsafe_compareAndSwapInt();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInvariants.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkInvariants.cpp.incl"
+
+int SharkTargetInvariants::count_monitors() {
+  int result = 0;
+  if (is_synchronized() || target()->has_monitor_bytecodes()) {
+    for (int i = 0; i < flow()->block_count(); i++) {
+      result = MAX2(result, flow()->pre_order_at(i)->monitor_count());
+    }
+  }
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInvariants.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// Base classes used to track various values through the compilation.
+// SharkCompileInvariants is used to track values which remain the
+// same for the top-level method and any inlined methods it may have
+// (ie for the whole compilation).  SharkTargetInvariants is used to
+// track values which differ between methods.
+
+class SharkCompileInvariants : public ResourceObj {
+ protected:
+  SharkCompileInvariants(ciEnv* env, SharkBuilder* builder)
+    : _env(env),
+      _builder(builder),
+      _thread(NULL) {}
+
+  SharkCompileInvariants(const SharkCompileInvariants* parent)
+    : _env(parent->_env),
+      _builder(parent->_builder),
+      _thread(parent->_thread) {}
+
+ private:
+  ciEnv*        _env;
+  SharkBuilder* _builder;
+  llvm::Value*  _thread;
+
+  // Top-level broker for HotSpot's Compiler Interface.
+  //
+  // Its main purpose is to allow the various CI classes to access
+  // oops in the VM without having to worry about safepointing.  In
+  // addition to this it acts as a holder for various recorders and
+  // memory allocators.
+  //
+  // Accessing this directly is kind of ugly, so it's private.  Add
+  // new accessors below if you need something from it.
+ private:
+  ciEnv* env() const {
+    assert(_env != NULL, "env not available");
+    return _env;
+  }
+
+  // The SharkBuilder that is used to build LLVM IR.
+ protected:
+  SharkBuilder* builder() const {
+    return _builder;
+  }
+
+  // Pointer to this thread's JavaThread object.  This is not
+  // available until a short way into SharkFunction creation
+  // so a setter is required.  Assertions are used to enforce
+  // invariance.
+ protected:
+  llvm::Value* thread() const {
+    assert(_thread != NULL, "thread not available");
+    return _thread;
+  }
+  void set_thread(llvm::Value* thread) {
+    assert(_thread == NULL, "thread already set");
+    _thread = thread;
+  }
+
+  // Objects that handle various aspects of the compilation.
+ protected:
+  DebugInformationRecorder* debug_info() const {
+    return env()->debug_info();
+  }
+  Dependencies* dependencies() const {
+    return env()->dependencies();
+  }
+  SharkCodeBuffer* code_buffer() const {
+    return builder()->code_buffer();
+  }
+
+  // Commonly used classes
+ protected:
+  ciInstanceKlass* java_lang_Object_klass() const {
+    return env()->Object_klass();
+  }
+  ciInstanceKlass* java_lang_Throwable_klass() const {
+    return env()->Throwable_klass();
+  }
+};
+
+class SharkTargetInvariants : public SharkCompileInvariants {
+ protected:
+  SharkTargetInvariants(ciEnv* env, SharkBuilder* builder, ciTypeFlow* flow)
+    : SharkCompileInvariants(env, builder),
+      _target(flow->method()),
+      _flow(flow),
+      _max_monitors(count_monitors()) {}
+
+  SharkTargetInvariants(const SharkCompileInvariants* parent, ciMethod* target)
+    : SharkCompileInvariants(parent),
+      _target(target),
+      _flow(NULL),
+      _max_monitors(count_monitors()) {}
+
+  SharkTargetInvariants(const SharkTargetInvariants* parent)
+    : SharkCompileInvariants(parent),
+      _target(parent->_target),
+      _flow(parent->_flow),
+      _max_monitors(parent->_max_monitors) {}
+
+ private:
+  int count_monitors();
+
+ private:
+  ciMethod*   _target;
+  ciTypeFlow* _flow;
+  int         _max_monitors;
+
+  // The method being compiled.
+ protected:
+  ciMethod* target() const {
+    return _target;
+  }
+
+  // Typeflow analysis of the method being compiled.
+ protected:
+  ciTypeFlow* flow() const {
+    assert(_flow != NULL, "typeflow not available");
+    return _flow;
+  }
+
+  // Properties of the method.
+ protected:
+  int max_locals() const {
+    return target()->max_locals();
+  }
+  int max_stack() const {
+    return target()->max_stack();
+  }
+  int max_monitors() const {
+    return _max_monitors;
+  }
+  int arg_size() const {
+    return target()->arg_size();
+  }
+  bool is_static() const {
+    return target()->is_static();
+  }
+  bool is_synchronized() const {
+    return target()->is_synchronized();
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkMemoryManager.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkMemoryManager.cpp.incl"
+
+using namespace llvm;
+
+void SharkMemoryManager::AllocateGOT() {
+  mm()->AllocateGOT();
+}
+
+unsigned char* SharkMemoryManager::getGOTBase() const {
+  return mm()->getGOTBase();
+}
+
+unsigned char* SharkMemoryManager::allocateStub(const GlobalValue* F,
+                                                unsigned StubSize,
+                                                unsigned Alignment) {
+  return mm()->allocateStub(F, StubSize, Alignment);
+}
+
+unsigned char* SharkMemoryManager::startFunctionBody(const Function* F,
+                                                     uintptr_t& ActualSize) {
+  return mm()->startFunctionBody(F, ActualSize);
+}
+
+void SharkMemoryManager::endFunctionBody(const Function* F,
+                                         unsigned char* FunctionStart,
+                                         unsigned char* FunctionEnd) {
+  mm()->endFunctionBody(F, FunctionStart, FunctionEnd);
+
+  SharkEntry *entry = get_entry_for_function(F);
+  if (entry != NULL)
+    entry->set_code_limit(FunctionEnd);
+}
+
+unsigned char* SharkMemoryManager::startExceptionTable(const Function* F,
+                                                       uintptr_t& ActualSize) {
+  return mm()->startExceptionTable(F, ActualSize);
+}
+
+void SharkMemoryManager::endExceptionTable(const Function* F,
+                                           unsigned char* TableStart,
+                                           unsigned char* TableEnd,
+                                           unsigned char* FrameRegister) {
+  mm()->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
+}
+
+void SharkMemoryManager::setMemoryWritable() {
+  mm()->setMemoryWritable();
+}
+
+void SharkMemoryManager::setMemoryExecutable() {
+  mm()->setMemoryExecutable();
+}
+
+#if SHARK_LLVM_VERSION >= 27
+void SharkMemoryManager::deallocateExceptionTable(void *ptr) {
+  mm()->deallocateExceptionTable(ptr);
+}
+
+void SharkMemoryManager::deallocateFunctionBody(void *ptr) {
+  mm()->deallocateFunctionBody(ptr);
+}
+#else
+void SharkMemoryManager::deallocateMemForFunction(const Function* F) {
+  return mm()->deallocateMemForFunction(F);
+}
+#endif
+
+uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size,
+                                            unsigned int Alignment) {
+  return mm()->allocateGlobal(Size, Alignment);
+}
+
+#if SHARK_LLVM_VERSION < 27
+void* SharkMemoryManager::getDlsymTable() const {
+  return mm()->getDlsymTable();
+}
+
+void SharkMemoryManager::SetDlsymTable(void *ptr) {
+  mm()->SetDlsymTable(ptr);
+}
+#endif
+
+void SharkMemoryManager::setPoisonMemory(bool poison) {
+  mm()->setPoisonMemory(poison);
+}
+
+unsigned char *SharkMemoryManager::allocateSpace(intptr_t Size,
+                                                 unsigned int Alignment) {
+  return mm()->allocateSpace(Size, Alignment);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkMemoryManager.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// SharkMemoryManager wraps the LLVM JIT Memory Manager.  We could use
+// this to run our own memory allocation policies, but for now all we
+// use it for is figuring out where the resulting native code ended up.
+
+class SharkMemoryManager : public llvm::JITMemoryManager {
+ public:
+  SharkMemoryManager()
+    : _mm(llvm::JITMemoryManager::CreateDefaultMemManager()) {}
+
+ private:
+  llvm::JITMemoryManager* _mm;
+
+ private:
+  llvm::JITMemoryManager* mm() const {
+    return _mm;
+  }
+
+ private:
+  std::map<const llvm::Function*, SharkEntry*> _entry_map;
+
+ public:
+  void set_entry_for_function(const llvm::Function* function,
+                              SharkEntry*           entry) {
+    _entry_map[function] = entry;
+  }
+  SharkEntry* get_entry_for_function(const llvm::Function* function) {
+    return _entry_map[function];
+  }
+
+ public:
+  void AllocateGOT();
+  unsigned char* getGOTBase() const;
+  unsigned char* allocateStub(const llvm::GlobalValue* F,
+                              unsigned StubSize,
+                              unsigned Alignment);
+  unsigned char* startFunctionBody(const llvm::Function* F,
+                                   uintptr_t& ActualSize);
+  void endFunctionBody(const llvm::Function* F,
+                       unsigned char* FunctionStart,
+                       unsigned char* FunctionEnd);
+  unsigned char* startExceptionTable(const llvm::Function* F,
+                                     uintptr_t& ActualSize);
+  void endExceptionTable(const llvm::Function* F,
+                         unsigned char* TableStart,
+                         unsigned char* TableEnd,
+                         unsigned char* FrameRegister);
+#if SHARK_LLVM_VERSION < 27
+  void* getDlsymTable() const;
+  void SetDlsymTable(void *ptr);
+#endif
+  void setPoisonMemory(bool);
+  uint8_t* allocateGlobal(uintptr_t, unsigned int);
+  void setMemoryWritable();
+  void setMemoryExecutable();
+#if SHARK_LLVM_VERSION >= 27
+  void deallocateExceptionTable(void *ptr);
+  void deallocateFunctionBody(void *ptr);
+#else
+  void deallocateMemForFunction(const llvm::Function* F);
+#endif
+  unsigned char *allocateSpace(intptr_t Size,
+                               unsigned int Alignment);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkNativeWrapper.cpp.incl"
+
+using namespace llvm;
+
+void SharkNativeWrapper::initialize(const char *name) {
+  // Create the function
+  _function = Function::Create(
+    SharkType::entry_point_type(),
+    GlobalVariable::InternalLinkage,
+    name);
+
+  // Get our arguments
+  Function::arg_iterator ai = function()->arg_begin();
+  Argument *method = ai++;
+  method->setName("method");
+  Argument *base_pc = ai++;
+  base_pc->setName("base_pc");
+  code_buffer()->set_base_pc(base_pc);
+  Argument *thread = ai++;
+  thread->setName("thread");
+  set_thread(thread);
+
+  // Create and push our stack frame
+  builder()->SetInsertPoint(CreateBlock());
+  _stack = SharkStack::CreateBuildAndPushFrame(this, method);
+  NOT_PRODUCT(method = NULL);
+
+  // Create the oopmap.  We use the one oopmap for every call site in
+  // the wrapper, which results in the odd mild inefficiency but is a
+  // damn sight easier to code.
+  OopMap *oopmap = new OopMap(
+    SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()),
+    SharkStack::oopmap_slot_munge(arg_size()));
+  oopmap->set_oop(SharkStack::slot2reg(stack()->method_slot_offset()));
+
+  // Set up the oop_tmp slot if required:
+  //  - For static methods we use it to handlize the class argument
+  //    for the call, and to protect the same during slow path locks
+  //    (if synchronized).
+  //  - For methods returning oops, we use it to protect the return
+  //    value across safepoints or slow path unlocking.
+  if (is_static() || is_returning_oop()) {
+    _oop_tmp_slot = stack()->slot_addr(
+      stack()->oop_tmp_slot_offset(),
+      SharkType::oop_type(),
+      "oop_tmp_slot");
+
+    oopmap->set_oop(SharkStack::slot2reg(stack()->oop_tmp_slot_offset()));
+  }
+
+  // Set up the monitor slot, for synchronized methods
+  if (is_synchronized()) {
+    Unimplemented();
+    _lock_slot_offset = 23;
+  }
+
+  // Start building the argument list
+  std::vector<const Type*> param_types;
+  std::vector<Value*> param_values;
+  const PointerType *box_type = PointerType::getUnqual(SharkType::oop_type());
+
+  // First argument is the JNIEnv
+  param_types.push_back(SharkType::jniEnv_type());
+  param_values.push_back(
+    builder()->CreateAddressOfStructEntry(
+      thread,
+      JavaThread::jni_environment_offset(),
+      SharkType::jniEnv_type(),
+      "jni_environment"));
+
+  // For static methods, the second argument is the class
+  if (is_static()) {
+    builder()->CreateStore(
+      builder()->CreateInlineOop(
+        JNIHandles::make_local(
+          target()->method_holder()->klass_part()->java_mirror())),
+      oop_tmp_slot());
+
+    param_types.push_back(box_type);
+    param_values.push_back(oop_tmp_slot());
+
+    _receiver_slot_offset = stack()->oop_tmp_slot_offset();
+  }
+  else if (is_returning_oop()) {
+    // The oop_tmp slot is registered in the oopmap,
+    // so we need to clear it.  This is one of the
+    // mild inefficiencies I mentioned earlier.
+    builder()->CreateStore(LLVMValue::null(), oop_tmp_slot());
+  }
+
+  // Parse the arguments
+  for (int i = 0; i < arg_size(); i++) {
+    int slot_offset = stack()->locals_slots_offset() + arg_size() - 1 - i;
+    int adjusted_offset = slot_offset;
+    BasicBlock *null, *not_null, *merge;
+    Value *box;
+    PHINode *phi;
+
+    switch (arg_type(i)) {
+    case T_VOID:
+      break;
+
+    case T_OBJECT:
+    case T_ARRAY:
+      null     = CreateBlock("null");
+      not_null = CreateBlock("not_null");
+      merge    = CreateBlock("merge");
+
+      box = stack()->slot_addr(slot_offset, SharkType::oop_type());
+      builder()->CreateCondBr(
+        builder()->CreateICmp(
+          ICmpInst::ICMP_EQ,
+          builder()->CreateLoad(box),
+          LLVMValue::null()),
+        null, not_null);
+
+      builder()->SetInsertPoint(null);
+      builder()->CreateBr(merge);
+
+      builder()->SetInsertPoint(not_null);
+      builder()->CreateBr(merge);
+
+      builder()->SetInsertPoint(merge);
+      phi = builder()->CreatePHI(box_type, "boxed_object");
+      phi->addIncoming(ConstantPointerNull::get(box_type), null);
+      phi->addIncoming(box, not_null);
+      box = phi;
+
+      param_types.push_back(box_type);
+      param_values.push_back(box);
+
+      oopmap->set_oop(SharkStack::slot2reg(slot_offset));
+
+      if (i == 0 && !is_static())
+        _receiver_slot_offset = slot_offset;
+
+      break;
+
+    case T_LONG:
+    case T_DOUBLE:
+      adjusted_offset--;
+      // fall through
+
+    default:
+      const Type *param_type = SharkType::to_stackType(arg_type(i));
+
+      param_types.push_back(param_type);
+      param_values.push_back(
+        builder()->CreateLoad(stack()->slot_addr(adjusted_offset, param_type)));
+    }
+  }
+
+  // The oopmap is now complete, and everything is written
+  // into the frame except the PC.
+  int pc_offset = code_buffer()->create_unique_offset();
+
+  _oop_maps = new OopMapSet();
+  oop_maps()->add_gc_map(pc_offset, oopmap);
+
+  builder()->CreateStore(
+    builder()->code_buffer_address(pc_offset),
+    stack()->slot_addr(stack()->pc_slot_offset()));
+
+  // Set up the Java frame anchor
+  stack()->CreateSetLastJavaFrame();
+
+  // Lock if necessary
+  if (is_synchronized())
+    Unimplemented();
+
+  // Change the thread state to _thread_in_native
+  CreateSetThreadState(_thread_in_native);
+
+  // Make the call
+  BasicType result_type = target()->result_type();
+  const Type* return_type;
+  if (result_type == T_VOID)
+    return_type = SharkType::void_type();
+  else if (is_returning_oop())
+    return_type = box_type;
+  else
+    return_type = SharkType::to_arrayType(result_type);
+  Value* native_function = builder()->CreateIntToPtr(
+     LLVMValue::intptr_constant((intptr_t) target()->native_function()),
+     PointerType::getUnqual(
+       FunctionType::get(return_type, param_types, false)));
+  Value *result = builder()->CreateCall(
+    native_function, param_values.begin(), param_values.end());
+
+  // Start the transition back to _thread_in_Java
+  CreateSetThreadState(_thread_in_native_trans);
+
+  // Make sure new state is visible in the GC thread
+  if (os::is_MP()) {
+    if (UseMembar)
+      builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD);
+    else
+      CreateWriteMemorySerializePage();
+  }
+
+  // Handle safepoint operations, pending suspend requests,
+  // and pending asynchronous exceptions.
+  BasicBlock *check_thread = CreateBlock("check_thread");
+  BasicBlock *do_safepoint = CreateBlock("do_safepoint");
+  BasicBlock *safepointed  = CreateBlock("safepointed");
+
+  Value *global_state = builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      LLVMValue::intptr_constant(
+        (intptr_t) SafepointSynchronize::address_of_state()),
+      PointerType::getUnqual(SharkType::jint_type())),
+    "global_state");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      global_state,
+      LLVMValue::jint_constant(SafepointSynchronize::_not_synchronized)),
+    do_safepoint, check_thread);
+
+  builder()->SetInsertPoint(check_thread);
+  Value *thread_state = builder()->CreateValueOfStructEntry(
+    thread,
+    JavaThread::suspend_flags_offset(),
+    SharkType::jint_type(),
+    "thread_state");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      thread_state,
+      LLVMValue::jint_constant(0)),
+    do_safepoint, safepointed);
+
+  builder()->SetInsertPoint(do_safepoint);
+  builder()->CreateCall(
+    builder()->check_special_condition_for_native_trans(), thread);
+  builder()->CreateBr(safepointed);
+
+  // Finally we can change the thread state to _thread_in_Java
+  builder()->SetInsertPoint(safepointed);
+  CreateSetThreadState(_thread_in_Java);
+
+  // Clear the frame anchor
+  stack()->CreateResetLastJavaFrame();
+
+  // If there is a pending exception then we can just unwind and
+  // return.  It seems totally wrong that unlocking is skipped here
+  // but apparently the template interpreter does this so we do too.
+  BasicBlock *exception    = CreateBlock("exception");
+  BasicBlock *no_exception = CreateBlock("no_exception");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      CreateLoadPendingException(),
+      LLVMValue::null()),
+    no_exception, exception);
+
+  builder()->SetInsertPoint(exception);
+  CreateResetHandleBlock();
+  stack()->CreatePopFrame(0);
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+
+  builder()->SetInsertPoint(no_exception);
+
+  // If the result was an oop then unbox it before
+  // releasing the handle it might be protected by
+  if (is_returning_oop()) {
+    BasicBlock *null     = builder()->GetInsertBlock();
+    BasicBlock *not_null = CreateBlock("not_null");
+    BasicBlock *merge    = CreateBlock("merge");
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(result, ConstantPointerNull::get(box_type)),
+      not_null, merge);
+
+    builder()->SetInsertPoint(not_null);
+    Value *unboxed_result = builder()->CreateLoad(result);
+    builder()->CreateBr(merge);
+
+    builder()->SetInsertPoint(merge);
+    PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "result");
+    phi->addIncoming(LLVMValue::null(), null);
+    phi->addIncoming(unboxed_result, not_null);
+    result = phi;
+  }
+
+  // Reset handle block
+  CreateResetHandleBlock();
+
+  // Unlock if necessary.
+  if (is_synchronized())
+    Unimplemented();
+
+  // Unwind and return
+  Value *result_addr = stack()->CreatePopFrame(type2size[result_type]);
+  if (result_type != T_VOID) {
+    bool needs_cast = false;
+    bool is_signed = false;
+    switch (result_type) {
+    case T_BOOLEAN:
+      result = builder()->CreateICmpNE(result, LLVMValue::jbyte_constant(0));
+      needs_cast = true;
+      break;
+
+    case T_CHAR:
+      needs_cast = true;
+      break;
+
+    case T_BYTE:
+    case T_SHORT:
+      needs_cast = true;
+      is_signed = true;
+      break;
+    }
+    if (needs_cast) {
+      result = builder()->CreateIntCast(
+        result, SharkType::to_stackType(result_type), is_signed);
+    }
+
+    builder()->CreateStore(
+      result,
+      builder()->CreateIntToPtr(
+        result_addr,
+        PointerType::getUnqual(SharkType::to_stackType(result_type))));
+  }
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkNativeWrapper : public SharkCompileInvariants {
+  friend class SharkStackWithNativeFrame;
+
+ public:
+  static SharkNativeWrapper* build(SharkBuilder* builder,
+                                   methodHandle  target,
+                                   const char*   name,
+                                   BasicType*    arg_types,
+                                   BasicType     return_type) {
+    return new SharkNativeWrapper(builder,
+                                  target,
+                                  name,
+                                  arg_types,
+                                  return_type);
+  }
+
+ private:
+  SharkNativeWrapper(SharkBuilder* builder,
+                     methodHandle  target,
+                     const char*   name,
+                     BasicType*    arg_types,
+                     BasicType     return_type)
+    : SharkCompileInvariants(NULL, builder),
+      _target(target),
+      _arg_types(arg_types),
+      _return_type(return_type),
+      _lock_slot_offset(0) { initialize(name); }
+
+ private:
+  void initialize(const char* name);
+
+ private:
+  methodHandle    _target;
+  BasicType*      _arg_types;
+  BasicType       _return_type;
+  llvm::Function* _function;
+  SharkStack*     _stack;
+  llvm::Value*    _oop_tmp_slot;
+  OopMapSet*      _oop_maps;
+  int             _receiver_slot_offset;
+  int             _lock_slot_offset;
+
+  // The method being compiled.
+ protected:
+  methodHandle target() const {
+    return _target;
+  }
+
+  // Properties of the method.
+ protected:
+  int arg_size() const {
+    return target()->size_of_parameters();
+  }
+  BasicType arg_type(int i) const {
+    return _arg_types[i];
+  }
+  BasicType return_type() const {
+    return _return_type;
+  }
+  bool is_static() const {
+    return target()->is_static();
+  }
+  bool is_synchronized() const {
+    return target()->is_synchronized();
+  }
+  bool is_returning_oop() const {
+    return target()->is_returning_oop();
+  }
+
+  // The LLVM function we are building.
+ public:
+  llvm::Function* function() const {
+    return _function;
+  }
+
+  // The Zero stack and our frame on it.
+ protected:
+  SharkStack* stack() const {
+    return _stack;
+  }
+
+  // Temporary oop storage.
+ protected:
+  llvm::Value* oop_tmp_slot() const {
+    assert(is_static() || is_returning_oop(), "should be");
+    return _oop_tmp_slot;
+  }
+
+  // Information required by nmethod::new_native_nmethod().
+ public:
+  int frame_size() const {
+    return stack()->oopmap_frame_size();
+  }
+  ByteSize receiver_offset() const {
+    return in_ByteSize(_receiver_slot_offset * wordSize);
+  }
+  ByteSize lock_offset() const {
+    return in_ByteSize(_lock_slot_offset * wordSize);
+  }
+  OopMapSet* oop_maps() const {
+    return _oop_maps;
+  }
+
+  // Helpers.
+ private:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const {
+    return llvm::BasicBlock::Create(SharkContext::current(), name, function());
+  }
+  llvm::Value* thread_state_address() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(), JavaThread::thread_state_offset(),
+      llvm::PointerType::getUnqual(SharkType::jint_type()),
+      "thread_state_address");
+  }
+  llvm::Value* pending_exception_address() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(), Thread::pending_exception_offset(),
+      llvm::PointerType::getUnqual(SharkType::oop_type()),
+      "pending_exception_address");
+  }
+  void CreateSetThreadState(JavaThreadState state) const {
+    builder()->CreateStore(
+      LLVMValue::jint_constant(state), thread_state_address());
+  }
+  void CreateWriteMemorySerializePage() const {
+    builder()->CreateStore(
+      LLVMValue::jint_constant(1),
+      builder()->CreateIntToPtr(
+        builder()->CreateAdd(
+          LLVMValue::intptr_constant(
+            (intptr_t) os::get_memory_serialize_page()),
+          builder()->CreateAnd(
+            builder()->CreateLShr(
+              builder()->CreatePtrToInt(thread(), SharkType::intptr_type()),
+              LLVMValue::intptr_constant(os::get_serialize_page_shift_count())),
+            LLVMValue::intptr_constant(os::get_serialize_page_mask()))),
+        llvm::PointerType::getUnqual(SharkType::jint_type())));
+  }
+  void CreateResetHandleBlock() const {
+    llvm::Value *active_handles = builder()->CreateValueOfStructEntry(
+      thread(),
+      JavaThread::active_handles_offset(),
+      SharkType::jniHandleBlock_type(),
+      "active_handles");
+    builder()->CreateStore(
+      LLVMValue::intptr_constant(0),
+      builder()->CreateAddressOfStructEntry(
+        active_handles,
+        in_ByteSize(JNIHandleBlock::top_offset_in_bytes()),
+        llvm::PointerType::getUnqual(SharkType::intptr_type()),
+        "top"));
+  }
+  llvm::LoadInst* CreateLoadPendingException() const {
+    return builder()->CreateLoad(
+      pending_exception_address(), "pending_exception");
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkRuntime.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkRuntime.cpp.incl"
+
+using namespace llvm;
+
+JRT_ENTRY(int, SharkRuntime::find_exception_handler(JavaThread* thread,
+                                                    int*        indexes,
+                                                    int         num_indexes))
+  constantPoolHandle pool(thread, method(thread)->constants());
+  KlassHandle exc_klass(thread, ((oop) tos_at(thread, 0))->klass());
+
+  for (int i = 0; i < num_indexes; i++) {
+    klassOop tmp = pool->klass_at(indexes[i], CHECK_0);
+    KlassHandle chk_klass(thread, tmp);
+
+    if (exc_klass() == chk_klass())
+      return i;
+
+    if (exc_klass()->klass_part()->is_subtype_of(chk_klass()))
+      return i;
+  }
+
+  return -1;
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::monitorenter(JavaThread*      thread,
+                                           BasicObjectLock* lock))
+  if (PrintBiasedLockingStatistics)
+    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
+
+  Handle object(thread, lock->obj());
+  assert(Universe::heap()->is_in_reserved_or_null(object()), "should be");
+  if (UseBiasedLocking) {
+    // Retry fast entry if bias is revoked to avoid unnecessary inflation
+    ObjectSynchronizer::fast_enter(object, lock->lock(), true, CHECK);
+  } else {
+    ObjectSynchronizer::slow_enter(object, lock->lock(), CHECK);
+  }
+  assert(Universe::heap()->is_in_reserved_or_null(lock->obj()), "should be");
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::monitorexit(JavaThread*      thread,
+                                          BasicObjectLock* lock))
+  Handle object(thread, lock->obj());
+  assert(Universe::heap()->is_in_reserved_or_null(object()), "should be");
+  if (lock == NULL || object()->is_unlocked()) {
+    THROW(vmSymbols::java_lang_IllegalMonitorStateException());
+  }
+  ObjectSynchronizer::slow_exit(object(), lock->lock(), thread);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::new_instance(JavaThread* thread, int index))
+  klassOop k_oop = method(thread)->constants()->klass_at(index, CHECK);
+  instanceKlassHandle klass(THREAD, k_oop);
+
+  // Make sure we are not instantiating an abstract klass
+  klass->check_valid_for_instantiation(true, CHECK);
+
+  // Make sure klass is initialized
+  klass->initialize(CHECK);
+
+  // At this point the class may not be fully initialized
+  // because of recursive initialization. If it is fully
+  // initialized & has_finalized is not set, we rewrite
+  // it into its fast version (Note: no locking is needed
+  // here since this is an atomic byte write and can be
+  // done more than once).
+  //
+  // Note: In case of classes with has_finalized we don't
+  //       rewrite since that saves us an extra check in
+  //       the fast version which then would call the
+  //       slow version anyway (and do a call back into
+  //       Java).
+  //       If we have a breakpoint, then we don't rewrite
+  //       because the _breakpoint bytecode would be lost.
+  oop obj = klass->allocate_instance(CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::newarray(JavaThread* thread,
+                                       BasicType   type,
+                                       int         size))
+  oop obj = oopFactory::new_typeArray(type, size, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::anewarray(JavaThread* thread,
+                                        int         index,
+                                        int         size))
+  klassOop klass = method(thread)->constants()->klass_at(index, CHECK);
+  objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::multianewarray(JavaThread* thread,
+                                             int         index,
+                                             int         ndims,
+                                             int*        dims))
+  klassOop klass = method(thread)->constants()->klass_at(index, CHECK);
+  oop obj = arrayKlass::cast(klass)->multi_allocate(ndims, dims, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::register_finalizer(JavaThread* thread,
+                                                 oop         object))
+  assert(object->is_oop(), "should be");
+  assert(object->klass()->klass_part()->has_finalizer(), "should have");
+  instanceKlass::register_finalizer(instanceOop(object), CHECK);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_ArithmeticException(JavaThread* thread,
+                                                        const char* file,
+                                                        int         line))
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_ArithmeticException(),
+    "");
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException(
+                                                     JavaThread* thread,
+                                                     const char* file,
+                                                     int         line,
+                                                     int         index))
+  char msg[jintAsStringSize];
+  snprintf(msg, sizeof(msg), "%d", index);
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_ArrayIndexOutOfBoundsException(),
+    msg);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_ClassCastException(JavaThread* thread,
+                                                       const char* file,
+                                                       int         line))
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_ClassCastException(),
+    "");
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread,
+                                                         const char* file,
+                                                         int         line))
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_NullPointerException(),
+    "");
+JRT_END
+
+// Non-VM calls
+// Nothing in these must ever GC!
+
+void SharkRuntime::dump(const char *name, intptr_t value) {
+  oop valueOop = (oop) value;
+  tty->print("%s = ", name);
+  if (valueOop->is_oop(true))
+    valueOop->print_on(tty);
+  else if (value >= ' ' && value <= '~')
+    tty->print("'%c' (%d)", value, value);
+  else
+    tty->print("%p", value);
+  tty->print_cr("");
+}
+
+bool SharkRuntime::is_subtype_of(klassOop check_klass, klassOop object_klass) {
+  return object_klass->klass_part()->is_subtype_of(check_klass);
+}
+
+int SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) {
+  Thread *THREAD = thread;
+
+  // In C2, uncommon_trap_blob creates a frame, so all the various
+  // deoptimization functions expect to find the frame of the method
+  // being deopted one frame down on the stack.  We create a dummy
+  // frame to mirror this.
+  FakeStubFrame *stubframe = FakeStubFrame::build(CHECK_0);
+  thread->push_zero_frame(stubframe);
+
+  // Initiate the trap
+  thread->set_last_Java_frame();
+  Deoptimization::UnrollBlock *urb =
+    Deoptimization::uncommon_trap(thread, trap_request);
+  thread->reset_last_Java_frame();
+
+  // Pop our dummy frame and the frame being deoptimized
+  thread->pop_zero_frame();
+  thread->pop_zero_frame();
+
+  // Push skeleton frames
+  int number_of_frames = urb->number_of_frames();
+  for (int i = 0; i < number_of_frames; i++) {
+    intptr_t size = urb->frame_sizes()[i];
+    InterpreterFrame *frame = InterpreterFrame::build(size, CHECK_0);
+    thread->push_zero_frame(frame);
+  }
+
+  // Push another dummy frame
+  stubframe = FakeStubFrame::build(CHECK_0);
+  thread->push_zero_frame(stubframe);
+
+  // Fill in the skeleton frames
+  thread->set_last_Java_frame();
+  Deoptimization::unpack_frames(thread, Deoptimization::Unpack_uncommon_trap);
+  thread->reset_last_Java_frame();
+
+  // Pop our dummy frame
+  thread->pop_zero_frame();
+
+  // Fall back into the interpreter
+  return number_of_frames;
+}
+
+FakeStubFrame* FakeStubFrame::build(TRAPS) {
+  ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack();
+  stack->overflow_check(header_words, CHECK_NULL);
+
+  stack->push(0); // next_frame, filled in later
+  intptr_t *fp = stack->sp();
+  assert(fp - stack->sp() == next_frame_off, "should be");
+
+  stack->push(FAKE_STUB_FRAME);
+  assert(fp - stack->sp() == frame_type_off, "should be");
+
+  return (FakeStubFrame *) fp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkRuntime.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkRuntime : public AllStatic {
+  // VM calls
+ public:
+  static int find_exception_handler(JavaThread* thread,
+                                    int*        indexes,
+                                    int         num_indexes);
+
+  static void monitorenter(JavaThread* thread, BasicObjectLock* lock);
+  static void monitorexit(JavaThread* thread, BasicObjectLock* lock);
+
+  static void new_instance(JavaThread* thread, int index);
+  static void newarray(JavaThread* thread, BasicType type, int size);
+  static void anewarray(JavaThread* thread, int index, int size);
+  static void multianewarray(JavaThread* thread,
+                             int         index,
+                             int         ndims,
+                             int*        dims);
+
+  static void register_finalizer(JavaThread* thread, oop object);
+
+  static void throw_ArithmeticException(JavaThread* thread,
+                                        const char* file,
+                                        int         line);
+  static void throw_ArrayIndexOutOfBoundsException(JavaThread* thread,
+                                                   const char* file,
+                                                   int         line,
+                                                   int         index);
+  static void throw_ClassCastException(JavaThread* thread,
+                                       const char* file,
+                                       int         line);
+  static void throw_NullPointerException(JavaThread* thread,
+                                         const char* file,
+                                         int         line);
+
+  // Helpers for VM calls
+ private:
+  static const SharkFrame* last_frame(JavaThread *thread) {
+    return thread->last_frame().zero_sharkframe();
+  }
+  static methodOop method(JavaThread *thread) {
+    return last_frame(thread)->method();
+  }
+  static address bcp(JavaThread *thread, int bci) {
+    return method(thread)->code_base() + bci;
+  }
+  static int two_byte_index(JavaThread *thread, int bci) {
+    return Bytes::get_Java_u2(bcp(thread, bci) + 1);
+  }
+  static intptr_t tos_at(JavaThread *thread, int offset) {
+    return *(thread->zero_stack()->sp() + offset);
+  }
+
+  // Non-VM calls
+ public:
+  static void dump(const char *name, intptr_t value);
+  static bool is_subtype_of(klassOop check_klass, klassOop object_klass);
+  static int uncommon_trap(JavaThread* thread, int trap_request);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStack.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkStack.cpp.incl"
+
+using namespace llvm;
+
+void SharkStack::initialize(Value* method) {
+  bool setup_sp_and_method = (method != NULL);
+
+  int locals_words  = max_locals();
+  int extra_locals  = locals_words - arg_size();
+  int header_words  = SharkFrame::header_words;
+  int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size();
+  int stack_words   = max_stack();
+  int frame_words   = header_words + monitor_words + stack_words;
+
+  _extended_frame_size = frame_words + locals_words;
+
+  // Update the stack pointer
+  Value *stack_pointer = builder()->CreateSub(
+    CreateLoadStackPointer(),
+    LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));
+  CreateStackOverflowCheck(stack_pointer);
+  if (setup_sp_and_method)
+    CreateStoreStackPointer(stack_pointer);
+
+  // Create the frame
+  _frame = builder()->CreateIntToPtr(
+    stack_pointer,
+    PointerType::getUnqual(
+      ArrayType::get(SharkType::intptr_type(), extended_frame_size())),
+    "frame");
+  int offset = 0;
+
+  // Expression stack
+  _stack_slots_offset = offset;
+  offset += stack_words;
+
+  // Monitors
+  _monitors_slots_offset = offset;
+  offset += monitor_words;
+
+  // Temporary oop slot
+  _oop_tmp_slot_offset = offset++;
+
+  // Method pointer
+  _method_slot_offset = offset++;
+  if (setup_sp_and_method) {
+    builder()->CreateStore(
+      method, slot_addr(method_slot_offset(), SharkType::methodOop_type()));
+  }
+
+  // Unextended SP
+  builder()->CreateStore(stack_pointer, slot_addr(offset++));
+
+  // PC
+  _pc_slot_offset = offset++;
+
+  // Frame header
+  builder()->CreateStore(
+    LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), slot_addr(offset++));
+  Value *fp = slot_addr(offset++);
+
+  // Local variables
+  _locals_slots_offset = offset;
+  offset += locals_words;
+
+  // Push the frame
+  assert(offset == extended_frame_size(), "should do");
+  builder()->CreateStore(CreateLoadFramePointer(), fp);
+  CreateStoreFramePointer(
+    builder()->CreatePtrToInt(fp, SharkType::intptr_type()));
+}
+
+// This function should match ZeroStack::overflow_check
+void SharkStack::CreateStackOverflowCheck(Value* sp) {
+  BasicBlock *zero_ok  = CreateBlock("zero_stack_ok");
+  BasicBlock *overflow = CreateBlock("stack_overflow");
+  BasicBlock *abi_ok   = CreateBlock("abi_stack_ok");
+
+  // Check the Zero stack
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(sp, stack_base()),
+    overflow, zero_ok);
+
+  // Check the ABI stack
+  builder()->SetInsertPoint(zero_ok);
+  Value *stack_top = builder()->CreateSub(
+    builder()->CreateValueOfStructEntry(
+      thread(),
+      Thread::stack_base_offset(),
+      SharkType::intptr_type(),
+      "abi_base"),
+    builder()->CreateValueOfStructEntry(
+      thread(),
+      Thread::stack_size_offset(),
+      SharkType::intptr_type(),
+      "abi_size"));
+  Value *free_stack = builder()->CreateSub(
+    builder()->CreatePtrToInt(
+      builder()->CreateGetFrameAddress(),
+      SharkType::intptr_type(),
+      "abi_sp"),
+    stack_top);
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(
+      free_stack,
+      LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
+    overflow, abi_ok);
+
+  // Handle overflows
+  builder()->SetInsertPoint(overflow);
+  builder()->CreateCall(builder()->throw_StackOverflowError(), thread());
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+
+  builder()->SetInsertPoint(abi_ok);
+}
+
+Value* SharkStack::CreatePopFrame(int result_slots) {
+  assert(result_slots >= 0 && result_slots <= 2, "should be");
+  int locals_to_pop = max_locals() - result_slots;
+
+  Value *fp = CreateLoadFramePointer();
+  Value *sp = builder()->CreateAdd(
+    fp,
+    LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize));
+
+  CreateStoreStackPointer(sp);
+  CreateStoreFramePointer(
+    builder()->CreateLoad(
+      builder()->CreateIntToPtr(
+        fp, PointerType::getUnqual(SharkType::intptr_type()))));
+
+  return sp;
+}
+
+Value* SharkStack::slot_addr(int         offset,
+                             const Type* type,
+                             const char* name) const {
+  bool needs_cast = type && type != SharkType::intptr_type();
+
+  Value* result = builder()->CreateStructGEP(
+    _frame, offset, needs_cast ? "" : name);
+
+  if (needs_cast) {
+    result = builder()->CreateBitCast(
+      result, PointerType::getUnqual(type), name);
+  }
+  return result;
+}
+
+// The bits that differentiate stacks with normal and native frames on top
+
+SharkStack* SharkStack::CreateBuildAndPushFrame(SharkFunction* function,
+                                                Value*         method) {
+  return new SharkStackWithNormalFrame(function, method);
+}
+SharkStack* SharkStack::CreateBuildAndPushFrame(SharkNativeWrapper* wrapper,
+                                                Value*              method) {
+  return new SharkStackWithNativeFrame(wrapper, method);
+}
+
+SharkStackWithNormalFrame::SharkStackWithNormalFrame(SharkFunction* function,
+                                                     Value*         method)
+  : SharkStack(function), _function(function) {
+  // For normal frames, the stack pointer and the method slot will
+  // be set during each decache, so it is not necessary to do them
+  // at the time the frame is created.  However, we set them for
+  // non-PRODUCT builds to make crash dumps easier to understand.
+  initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method));
+}
+SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp,
+                                                     Value*              method)
+  : SharkStack(wrp), _wrapper(wrp) {
+  initialize(method);
+}
+
+int SharkStackWithNormalFrame::arg_size() const {
+  return function()->arg_size();
+}
+int SharkStackWithNativeFrame::arg_size() const {
+  return wrapper()->arg_size();
+}
+
+int SharkStackWithNormalFrame::max_locals() const {
+  return function()->max_locals();
+}
+int SharkStackWithNativeFrame::max_locals() const {
+  return wrapper()->arg_size();
+}
+
+int SharkStackWithNormalFrame::max_stack() const {
+  return function()->max_stack();
+}
+int SharkStackWithNativeFrame::max_stack() const {
+  return 0;
+}
+
+int SharkStackWithNormalFrame::max_monitors() const {
+  return function()->max_monitors();
+}
+int SharkStackWithNativeFrame::max_monitors() const {
+  return wrapper()->is_synchronized() ? 1 : 0;
+}
+
+BasicBlock* SharkStackWithNormalFrame::CreateBlock(const char* name) const {
+  return function()->CreateBlock(name);
+}
+BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const {
+  return wrapper()->CreateBlock(name);
+}
+
+address SharkStackWithNormalFrame::interpreter_entry_point() const {
+  return (address) CppInterpreter::normal_entry;
+}
+address SharkStackWithNativeFrame::interpreter_entry_point() const {
+  return (address) CppInterpreter::native_entry;
+}
+
+#ifndef PRODUCT
+void SharkStack::CreateAssertLastJavaSPIsNull() const {
+#ifdef ASSERT
+  BasicBlock *fail = CreateBlock("assert_failed");
+  BasicBlock *pass = CreateBlock("assert_ok");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      builder()->CreateLoad(last_Java_sp_addr()),
+      LLVMValue::intptr_constant(0)),
+    pass, fail);
+
+  builder()->SetInsertPoint(fail);
+  builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  builder()->SetInsertPoint(pass);
+#endif // ASSERT
+}
+#endif // !PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStack.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkFunction;
+class SharkNativeWrapper;
+class SharkStackWithNormalFrame;
+class SharkStackWithNativeFrame;
+
+class SharkStack : public SharkCompileInvariants {
+ public:
+  static SharkStack* CreateBuildAndPushFrame(
+    SharkFunction* function, llvm::Value* method);
+  static SharkStack* CreateBuildAndPushFrame(
+    SharkNativeWrapper* wrapper, llvm::Value* method);
+
+ protected:
+  SharkStack(const SharkCompileInvariants* parent)
+    : SharkCompileInvariants(parent) {}
+
+ protected:
+  void initialize(llvm::Value* method);
+
+ protected:
+  void CreateStackOverflowCheck(llvm::Value* sp);
+
+  // Properties of the method being compiled
+ protected:
+  virtual int arg_size() const = 0;
+  virtual int max_locals() const = 0;
+  virtual int max_stack() const = 0;
+  virtual int max_monitors() const = 0;
+
+  // BasicBlock creation
+ protected:
+  virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
+
+  // Interpreter entry point for bailouts
+ protected:
+  virtual address interpreter_entry_point() const = 0;
+
+  // Interface with the Zero stack
+ private:
+  llvm::Value* zero_stack() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::zero_stack_offset(),
+      SharkType::zeroStack_type(),
+      "zero_stack");
+  }
+  llvm::Value* stack_base() const {
+    return builder()->CreateValueOfStructEntry(
+      zero_stack(),
+      ZeroStack::base_offset(),
+      SharkType::intptr_type(),
+      "stack_base");
+  }
+  llvm::Value* stack_pointer_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      zero_stack(),
+      ZeroStack::sp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "stack_pointer_addr");
+  }
+  llvm::Value* frame_pointer_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::top_zero_frame_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "frame_pointer_addr");
+  }
+
+ public:
+  llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {
+    return builder()->CreateLoad(stack_pointer_addr(), name);
+  }
+  llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {
+    return builder()->CreateStore(value, stack_pointer_addr());
+  }
+  llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {
+    return builder()->CreateLoad(frame_pointer_addr(), name);
+  }
+  llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {
+    return builder()->CreateStore(value, frame_pointer_addr());
+  }
+  llvm::Value* CreatePopFrame(int result_slots);
+
+  // Interface with the frame anchor
+ private:
+  llvm::Value* last_Java_sp_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::last_Java_sp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "last_Java_sp_addr");
+  }
+  llvm::Value* last_Java_fp_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::last_Java_fp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "last_Java_fp_addr");
+  }
+
+ public:
+  void CreateSetLastJavaFrame() {
+    // Note that whenever _last_Java_sp != NULL other anchor fields
+    // must be valid.  The profiler apparently depends on this.
+    NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
+    builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
+    // XXX There's last_Java_pc as well, but I don't think anything uses it
+    // Also XXX: should we fence here?  Zero doesn't...
+    builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
+    // Also also XXX: we could probably cache the sp (and the fp we know??)
+  }
+  void CreateResetLastJavaFrame() {
+    builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
+  }
+
+ private:
+  void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
+
+  // Our method's frame
+ private:
+  llvm::Value* _frame;
+  int          _extended_frame_size;
+  int          _stack_slots_offset;
+
+ public:
+  int extended_frame_size() const {
+    return _extended_frame_size;
+  }
+  int oopmap_frame_size() const {
+    return extended_frame_size() - arg_size();
+  }
+
+  // Offsets of things in the frame
+ private:
+  int _monitors_slots_offset;
+  int _oop_tmp_slot_offset;
+  int _method_slot_offset;
+  int _pc_slot_offset;
+  int _locals_slots_offset;
+
+ public:
+  int stack_slots_offset() const {
+    return _stack_slots_offset;
+  }
+  int oop_tmp_slot_offset() const {
+    return _oop_tmp_slot_offset;
+  }
+  int method_slot_offset() const {
+    return _method_slot_offset;
+  }
+  int pc_slot_offset() const {
+    return _pc_slot_offset;
+  }
+  int locals_slots_offset() const {
+    return _locals_slots_offset;
+  }
+  int monitor_offset(int index) const {
+    assert(index >= 0 && index < max_monitors(), "invalid monitor index");
+    return _monitors_slots_offset +
+      (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();
+  }
+  int monitor_object_offset(int index) const {
+    return monitor_offset(index) +
+      (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);
+  }
+  int monitor_header_offset(int index) const {
+    return monitor_offset(index) +
+      ((BasicObjectLock::lock_offset_in_bytes() +
+        BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);
+  }
+
+  // Addresses of things in the frame
+ public:
+  llvm::Value* slot_addr(int               offset,
+                         const llvm::Type* type = NULL,
+                         const char*       name = "") const;
+
+  llvm::Value* monitor_addr(int index) const {
+    return slot_addr(
+      monitor_offset(index),
+      SharkType::monitor_type(),
+      "monitor");
+  }
+  llvm::Value* monitor_object_addr(int index) const {
+    return slot_addr(
+      monitor_object_offset(index),
+      SharkType::oop_type(),
+      "object_addr");
+  }
+  llvm::Value* monitor_header_addr(int index) const {
+    return slot_addr(
+      monitor_header_offset(index),
+      SharkType::intptr_type(),
+      "displaced_header_addr");
+  }
+
+  // oopmap helpers
+ public:
+  static int oopmap_slot_munge(int offset) {
+    return offset << (LogBytesPerWord - LogBytesPerInt);
+  }
+  static VMReg slot2reg(int offset) {
+    return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
+  }
+};
+
+class SharkStackWithNormalFrame : public SharkStack {
+  friend class SharkStack;
+
+ protected:
+  SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
+
+ private:
+  SharkFunction* _function;
+
+ private:
+  SharkFunction* function() const {
+    return _function;
+  }
+
+  // Properties of the method being compiled
+ private:
+  int arg_size() const;
+  int max_locals() const;
+  int max_stack() const;
+  int max_monitors() const;
+
+  // BasicBlock creation
+ private:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const;
+
+  // Interpreter entry point for bailouts
+ private:
+  address interpreter_entry_point() const;
+};
+
+class SharkStackWithNativeFrame : public SharkStack {
+  friend class SharkStack;
+
+ protected:
+  SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
+
+ private:
+  SharkNativeWrapper* _wrapper;
+
+ private:
+  SharkNativeWrapper* wrapper() const {
+    return _wrapper;
+  }
+
+  // Properties of the method being compiled
+ private:
+  int arg_size() const;
+  int max_locals() const;
+  int max_stack() const;
+  int max_monitors() const;
+
+  // BasicBlock creation
+ private:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const;
+
+  // Interpreter entry point for bailouts
+ private:
+  address interpreter_entry_point() const;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkState.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkState.cpp.incl"
+
+using namespace llvm;
+
+void SharkState::initialize(const SharkState *state) {
+  _locals = NEW_RESOURCE_ARRAY(SharkValue*, max_locals());
+  _stack  = NEW_RESOURCE_ARRAY(SharkValue*, max_stack());
+
+  NOT_PRODUCT(memset(_locals, 23, max_locals() * sizeof(SharkValue *)));
+  NOT_PRODUCT(memset(_stack,  23, max_stack()  * sizeof(SharkValue *)));
+  _sp = _stack;
+
+  if (state) {
+    for (int i = 0; i < max_locals(); i++) {
+      SharkValue *value = state->local(i);
+      if (value)
+        value = value->clone();
+      set_local(i, value);
+    }
+
+    for (int i = state->stack_depth() - 1; i >= 0; i--) {
+      SharkValue *value = state->stack(i);
+      if (value)
+        value = value->clone();
+      push(value);
+    }
+  }
+
+  set_num_monitors(state ? state->num_monitors() : 0);
+}
+
+bool SharkState::equal_to(SharkState *other) {
+  if (target() != other->target())
+    return false;
+
+  if (method() != other->method())
+    return false;
+
+  if (oop_tmp() != other->oop_tmp())
+    return false;
+
+  if (max_locals() != other->max_locals())
+    return false;
+
+  if (stack_depth() != other->stack_depth())
+    return false;
+
+  if (num_monitors() != other->num_monitors())
+    return false;
+
+  if (has_safepointed() != other->has_safepointed())
+    return false;
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    SharkValue *value = local(i);
+    SharkValue *other_value = other->local(i);
+
+    if (value == NULL) {
+      if (other_value != NULL)
+        return false;
+    }
+    else {
+      if (other_value == NULL)
+        return false;
+
+      if (!value->equal_to(other_value))
+        return false;
+    }
+  }
+
+  // Expression stack
+  for (int i = 0; i < stack_depth(); i++) {
+    SharkValue *value = stack(i);
+    SharkValue *other_value = other->stack(i);
+
+    if (value == NULL) {
+      if (other_value != NULL)
+        return false;
+    }
+    else {
+      if (other_value == NULL)
+        return false;
+
+      if (!value->equal_to(other_value))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+void SharkState::merge(SharkState* other,
+                       BasicBlock* other_block,
+                       BasicBlock* this_block) {
+  // Method
+  Value *this_method = this->method();
+  Value *other_method = other->method();
+  if (this_method != other_method) {
+    PHINode *phi = builder()->CreatePHI(SharkType::methodOop_type(), "method");
+    phi->addIncoming(this_method, this_block);
+    phi->addIncoming(other_method, other_block);
+    set_method(phi);
+  }
+
+  // Temporary oop slot
+  Value *this_oop_tmp = this->oop_tmp();
+  Value *other_oop_tmp = other->oop_tmp();
+  if (this_oop_tmp != other_oop_tmp) {
+    assert(this_oop_tmp && other_oop_tmp, "can't merge NULL with non-NULL");
+    PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "oop_tmp");
+    phi->addIncoming(this_oop_tmp, this_block);
+    phi->addIncoming(other_oop_tmp, other_block);
+    set_oop_tmp(phi);
+  }
+
+  // Monitors
+  assert(this->num_monitors() == other->num_monitors(), "should be");
+
+  // Local variables
+  assert(this->max_locals() == other->max_locals(), "should be");
+  for (int i = 0; i < max_locals(); i++) {
+    SharkValue *this_value = this->local(i);
+    SharkValue *other_value = other->local(i);
+    assert((this_value == NULL) == (other_value == NULL), "should be");
+    if (this_value != NULL) {
+      char name[18];
+      snprintf(name, sizeof(name), "local_%d_", i);
+      set_local(i, this_value->merge(
+        builder(), other_value, other_block, this_block, name));
+    }
+  }
+
+  // Expression stack
+  assert(this->stack_depth() == other->stack_depth(), "should be");
+  for (int i = 0; i < stack_depth(); i++) {
+    SharkValue *this_value = this->stack(i);
+    SharkValue *other_value = other->stack(i);
+    assert((this_value == NULL) == (other_value == NULL), "should be");
+    if (this_value != NULL) {
+      char name[18];
+      snprintf(name, sizeof(name), "stack_%d_", i);
+      set_stack(i, this_value->merge(
+        builder(), other_value, other_block, this_block, name));
+    }
+  }
+
+  // Safepointed status
+  set_has_safepointed(this->has_safepointed() && other->has_safepointed());
+}
+
+void SharkState::replace_all(SharkValue* old_value, SharkValue* new_value) {
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    if (local(i) == old_value)
+      set_local(i, new_value);
+  }
+
+  // Expression stack
+  for (int i = 0; i < stack_depth(); i++) {
+    if (stack(i) == old_value)
+      set_stack(i, new_value);
+  }
+}
+
+SharkNormalEntryState::SharkNormalEntryState(SharkTopLevelBlock* block,
+                                             Value*              method)
+  : SharkState(block) {
+  assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack");
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    ciType *type = block->local_type_at_entry(i);
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      if (i >= arg_size()) {
+        ShouldNotReachHere();
+      }
+      value = SharkValue::create_generic(type, NULL, i == 0 && !is_static());
+      break;
+
+    case ciTypeFlow::StateVector::T_NULL:
+      value = SharkValue::null();
+      break;
+
+    case ciTypeFlow::StateVector::T_BOTTOM:
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    set_local(i, value);
+  }
+  SharkNormalEntryCacher(block->function(), method).scan(this);
+}
+
+SharkOSREntryState::SharkOSREntryState(SharkTopLevelBlock* block,
+                                       Value*              method,
+                                       Value*              osr_buf)
+  : SharkState(block) {
+  assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack");
+  set_num_monitors(block->ciblock()->monitor_count());
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    ciType *type = block->local_type_at_entry(i);
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      value = SharkValue::create_generic(type, NULL, false);
+      break;
+
+    case ciTypeFlow::StateVector::T_NULL:
+      value = SharkValue::null();
+      break;
+
+    case ciTypeFlow::StateVector::T_BOTTOM:
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    set_local(i, value);
+  }
+  SharkOSREntryCacher(block->function(), method, osr_buf).scan(this);
+}
+
+SharkPHIState::SharkPHIState(SharkTopLevelBlock* block)
+  : SharkState(block), _block(block) {
+  BasicBlock *saved_insert_point = builder()->GetInsertBlock();
+  builder()->SetInsertPoint(block->entry_block());
+  char name[18];
+
+  // Method
+  set_method(builder()->CreatePHI(SharkType::methodOop_type(), "method"));
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    ciType *type = block->local_type_at_entry(i);
+    if (type->basic_type() == (BasicType) ciTypeFlow::StateVector::T_NULL) {
+      // XXX we could do all kinds of clever stuff here
+      type = ciType::make(T_OBJECT); // XXX what about T_ARRAY?
+    }
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      snprintf(name, sizeof(name), "local_%d_", i);
+      value = SharkValue::create_phi(
+        type, builder()->CreatePHI(SharkType::to_stackType(type), name));
+      break;
+
+    case T_ADDRESS:
+      value = SharkValue::address_constant(type->as_return_address()->bci());
+      break;
+
+    case ciTypeFlow::StateVector::T_BOTTOM:
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    set_local(i, value);
+  }
+
+  // Expression stack
+  for (int i = 0; i < block->stack_depth_at_entry(); i++) {
+    ciType *type = block->stack_type_at_entry(i);
+    if (type->basic_type() == (BasicType) ciTypeFlow::StateVector::T_NULL) {
+      // XXX we could do all kinds of clever stuff here
+      type = ciType::make(T_OBJECT); // XXX what about T_ARRAY?
+    }
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      snprintf(name, sizeof(name), "stack_%d_", i);
+      value = SharkValue::create_phi(
+        type, builder()->CreatePHI(SharkType::to_stackType(type), name));
+      break;
+
+    case T_ADDRESS:
+      value = SharkValue::address_constant(type->as_return_address()->bci());
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    push(value);
+  }
+
+  // Monitors
+  set_num_monitors(block->ciblock()->monitor_count());
+
+  builder()->SetInsertPoint(saved_insert_point);
+}
+
+void SharkPHIState::add_incoming(SharkState* incoming_state) {
+  BasicBlock *predecessor = builder()->GetInsertBlock();
+
+  // Method
+  ((PHINode *) method())->addIncoming(incoming_state->method(), predecessor);
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    if (local(i) != NULL)
+      local(i)->addIncoming(incoming_state->local(i), predecessor);
+  }
+
+  // Expression stack
+  int stack_depth = block()->stack_depth_at_entry();
+  assert(stack_depth == incoming_state->stack_depth(), "should be");
+  for (int i = 0; i < stack_depth; i++) {
+    assert((stack(i) == NULL) == (incoming_state->stack(i) == NULL), "oops");
+    if (stack(i))
+      stack(i)->addIncoming(incoming_state->stack(i), predecessor);
+  }
+
+  // Monitors
+  assert(num_monitors() == incoming_state->num_monitors(), "should be");
+
+  // Temporary oop slot
+  assert(oop_tmp() == incoming_state->oop_tmp(), "should be");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkState.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkState : public SharkTargetInvariants {
+ public:
+  SharkState(const SharkTargetInvariants* parent)
+    : SharkTargetInvariants(parent),
+      _method(NULL),
+      _oop_tmp(NULL),
+      _has_safepointed(false) { initialize(NULL); }
+
+  SharkState(const SharkState* state)
+    : SharkTargetInvariants(state),
+      _method(state->_method),
+      _oop_tmp(state->_oop_tmp),
+      _has_safepointed(state->_has_safepointed) { initialize(state); }
+
+ private:
+  void initialize(const SharkState* state);
+
+ private:
+  llvm::Value* _method;
+  SharkValue** _locals;
+  SharkValue** _stack;
+  SharkValue** _sp;
+  int          _num_monitors;
+  llvm::Value* _oop_tmp;
+  bool         _has_safepointed;
+
+  // Method
+ public:
+  llvm::Value** method_addr() {
+    return &_method;
+  }
+  llvm::Value* method() const {
+    return _method;
+  }
+ protected:
+  void set_method(llvm::Value* method) {
+    _method = method;
+  }
+
+  // Local variables
+ public:
+  SharkValue** local_addr(int index) const {
+    assert(index >= 0 && index < max_locals(), "bad local variable index");
+    return &_locals[index];
+  }
+  SharkValue* local(int index) const {
+    return *local_addr(index);
+  }
+  void set_local(int index, SharkValue* value) {
+    *local_addr(index) = value;
+  }
+
+  // Expression stack
+ public:
+  SharkValue** stack_addr(int slot) const {
+    assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
+    return &_sp[-(slot + 1)];
+  }
+  SharkValue* stack(int slot) const {
+    return *stack_addr(slot);
+  }
+ protected:
+  void set_stack(int slot, SharkValue* value) {
+    *stack_addr(slot) = value;
+  }
+ public:
+  int stack_depth() const {
+    return _sp - _stack;
+  }
+  void push(SharkValue* value) {
+    assert(stack_depth() < max_stack(), "stack overrun");
+    *(_sp++) = value;
+  }
+  SharkValue* pop() {
+    assert(stack_depth() > 0, "stack underrun");
+    return *(--_sp);
+  }
+
+  // Monitors
+ public:
+  int num_monitors() const {
+    return _num_monitors;
+  }
+  void set_num_monitors(int num_monitors) {
+    _num_monitors = num_monitors;
+  }
+
+  // Temporary oop slot
+ public:
+  llvm::Value** oop_tmp_addr() {
+    return &_oop_tmp;
+  }
+  llvm::Value* oop_tmp() const {
+    return _oop_tmp;
+  }
+  void set_oop_tmp(llvm::Value* oop_tmp) {
+    _oop_tmp = oop_tmp;
+  }
+
+  // Safepointed status
+ public:
+  bool has_safepointed() const {
+    return _has_safepointed;
+  }
+  void set_has_safepointed(bool has_safepointed) {
+    _has_safepointed = has_safepointed;
+  }
+
+  // Comparison
+ public:
+  bool equal_to(SharkState* other);
+
+  // Copy and merge
+ public:
+  SharkState* copy() const {
+    return new SharkState(this);
+  }
+  void merge(SharkState*       other,
+             llvm::BasicBlock* other_block,
+             llvm::BasicBlock* this_block);
+
+  // Value replacement
+ public:
+  void replace_all(SharkValue* old_value, SharkValue* new_value);
+};
+
+class SharkTopLevelBlock;
+
+// SharkNormalEntryState objects are used to create the state
+// that the method will be entered with for a normal invocation.
+class SharkNormalEntryState : public SharkState {
+ public:
+  SharkNormalEntryState(SharkTopLevelBlock* block,
+                        llvm::Value*        method);
+};
+
+// SharkOSREntryState objects are used to create the state
+// that the method will be entered with for an OSR invocation.
+class SharkOSREntryState : public SharkState {
+ public:
+  SharkOSREntryState(SharkTopLevelBlock* block,
+                     llvm::Value*        method,
+                     llvm::Value*        osr_buf);
+};
+
+// SharkPHIState objects are used to manage the entry state
+// for blocks with more than one entry path or for blocks
+// entered from blocks that will be compiled later.
+class SharkPHIState : public SharkState {
+ public:
+  SharkPHIState(SharkTopLevelBlock* block);
+
+ private:
+  SharkTopLevelBlock* _block;
+
+ private:
+  SharkTopLevelBlock* block() const {
+    return _block;
+  }
+
+ public:
+  void add_incoming(SharkState* incoming_state);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStateScanner.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkStateScanner.cpp.incl"
+
+using namespace llvm;
+
+void SharkStateScanner::scan(SharkState* state) {
+  start_frame();
+
+  // Expression stack
+  stack_integrity_checks(state);
+  start_stack(state->stack_depth());
+  for (int i = state->stack_depth() - 1; i >= 0; i--) {
+    process_stack_slot(
+      i,
+      state->stack_addr(i),
+      stack()->stack_slots_offset() +
+        i + max_stack() - state->stack_depth());
+  }
+  end_stack();
+
+  // Monitors
+  start_monitors(state->num_monitors());
+  for (int i = 0; i < state->num_monitors(); i++) {
+    process_monitor(
+      i,
+      stack()->monitor_offset(i),
+      stack()->monitor_object_offset(i));
+  }
+  end_monitors();
+
+  // Frame header
+  start_frame_header();
+  process_oop_tmp_slot(
+    state->oop_tmp_addr(), stack()->oop_tmp_slot_offset());
+  process_method_slot(state->method_addr(), stack()->method_slot_offset());
+  process_pc_slot(stack()->pc_slot_offset());
+  end_frame_header();
+
+  // Local variables
+  locals_integrity_checks(state);
+  start_locals();
+  for (int i = 0; i < max_locals(); i++) {
+    process_local_slot(
+      i,
+      state->local_addr(i),
+      stack()->locals_slots_offset() + max_locals() - 1 - i);
+  }
+  end_locals();
+
+  end_frame();
+}
+
+#ifndef PRODUCT
+void SharkStateScanner::stack_integrity_checks(SharkState* state) {
+  for (int i = 0; i < state->stack_depth(); i++) {
+    if (state->stack(i)) {
+      if (state->stack(i)->is_two_word())
+        assert(state->stack(i - 1) == NULL, "should be");
+    }
+    else {
+      assert(state->stack(i + 1)->is_two_word(), "should be");
+    }
+  }
+}
+
+void SharkStateScanner::locals_integrity_checks(SharkState* state) {
+  for (int i = 0; i < max_locals(); i++) {
+    if (state->local(i)) {
+      if (state->local(i)->is_two_word())
+        assert(state->local(i + 1) == NULL, "should be");
+    }
+  }
+}
+#endif // !PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStateScanner.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkState;
+
+class SharkStateScanner : public SharkTargetInvariants {
+ protected:
+  SharkStateScanner(SharkFunction* function)
+    : SharkTargetInvariants(function), _stack(function->stack()) {}
+
+ private:
+  SharkStack* _stack;
+
+ protected:
+  SharkStack* stack() const {
+    return _stack;
+  }
+
+  // Scan the frame
+ public:
+  void scan(SharkState* state);
+
+  // Callbacks
+  // Note that the offsets supplied to the various process_* callbacks
+  // are specified in wordSize words from the frame's unextended_sp.
+ protected:
+  virtual void start_frame()                                                 {}
+
+  virtual void start_stack(int stack_depth)                                  {}
+  virtual void process_stack_slot(int index, SharkValue** value, int offset) {}
+  virtual void end_stack()                                                   {}
+
+  virtual void start_monitors(int num_monitors)                              {}
+  virtual void process_monitor(int index, int box_offset, int obj_offset)    {}
+  virtual void end_monitors()                                                {}
+
+  virtual void start_frame_header()                                          {}
+  virtual void process_oop_tmp_slot(llvm::Value** value, int offset)         {}
+  virtual void process_method_slot(llvm::Value** value, int offset)          {}
+  virtual void process_pc_slot(int offset)                                   {}
+  virtual void end_frame_header()                                            {}
+
+  virtual void start_locals()                                                {}
+  virtual void process_local_slot(int index, SharkValue** value, int offset) {}
+  virtual void end_locals()                                                  {}
+
+  virtual void end_frame()                                                   {}
+
+  // Integrity checks
+ private:
+  void stack_integrity_checks(SharkState* state) PRODUCT_RETURN;
+  void locals_integrity_checks(SharkState* state) PRODUCT_RETURN;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,1995 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkTopLevelBlock.cpp.incl"
+
+using namespace llvm;
+
+void SharkTopLevelBlock::scan_for_traps() {
+  // If typeflow found a trap then don't scan past it
+  int limit_bci = ciblock()->has_trap() ? ciblock()->trap_bci() : limit();
+
+  // Scan the bytecode for traps that are always hit
+  iter()->reset_to_bci(start());
+  while (iter()->next_bci() < limit_bci) {
+    iter()->next();
+
+    ciField *field;
+    ciMethod *method;
+    ciInstanceKlass *klass;
+    bool will_link;
+    bool is_field;
+
+    switch (bc()) {
+    case Bytecodes::_ldc:
+    case Bytecodes::_ldc_w:
+      if (!SharkConstant::for_ldc(iter())->is_loaded()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret), bci());
+        return;
+      }
+      break;
+
+    case Bytecodes::_getfield:
+    case Bytecodes::_getstatic:
+    case Bytecodes::_putfield:
+    case Bytecodes::_putstatic:
+      field = iter()->get_field(will_link);
+      assert(will_link, "typeflow responsibility");
+      is_field = (bc() == Bytecodes::_getfield || bc() == Bytecodes::_putfield);
+
+      // If the bytecode does not match the field then bail out to
+      // the interpreter to throw an IncompatibleClassChangeError
+      if (is_field == field->is_static()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_unhandled,
+            Deoptimization::Action_none), bci());
+        return;
+      }
+
+      // Bail out if we are trying to access a static variable
+      // before the class initializer has completed.
+      if (!is_field && !field->holder()->is_initialized()) {
+        if (!static_field_ok_in_clinit(field)) {
+          set_trap(
+            Deoptimization::make_trap_request(
+              Deoptimization::Reason_uninitialized,
+              Deoptimization::Action_reinterpret), bci());
+          return;
+        }
+      }
+      break;
+
+    case Bytecodes::_invokestatic:
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_invokeinterface:
+      method = iter()->get_method(will_link);
+      assert(will_link, "typeflow responsibility");
+
+      if (!method->holder()->is_linked()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret), bci());
+          return;
+      }
+
+      if (bc() == Bytecodes::_invokevirtual) {
+        klass = ciEnv::get_instance_klass_for_declared_method_holder(
+          iter()->get_declared_method_holder());
+        if (!klass->is_linked()) {
+          set_trap(
+            Deoptimization::make_trap_request(
+              Deoptimization::Reason_uninitialized,
+              Deoptimization::Action_reinterpret), bci());
+            return;
+        }
+      }
+      break;
+
+    case Bytecodes::_new:
+      klass = iter()->get_klass(will_link)->as_instance_klass();
+      assert(will_link, "typeflow responsibility");
+
+      // Bail out if the class is unloaded
+      if (iter()->is_unresolved_klass() || !klass->is_initialized()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret), bci());
+        return;
+      }
+
+      // Bail out if the class cannot be instantiated
+      if (klass->is_abstract() || klass->is_interface() ||
+          klass->name() == ciSymbol::java_lang_Class()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_unhandled,
+            Deoptimization::Action_reinterpret), bci());
+        return;
+      }
+      break;
+    }
+  }
+
+  // Trap if typeflow trapped (and we didn't before)
+  if (ciblock()->has_trap()) {
+    set_trap(
+      Deoptimization::make_trap_request(
+        Deoptimization::Reason_unloaded,
+        Deoptimization::Action_reinterpret,
+        ciblock()->trap_index()), ciblock()->trap_bci());
+    return;
+  }
+}
+
+bool SharkTopLevelBlock::static_field_ok_in_clinit(ciField* field) {
+  assert(field->is_static(), "should be");
+
+  // This code is lifted pretty much verbatim from C2's
+  // Parse::static_field_ok_in_clinit() in parse3.cpp.
+  bool access_OK = false;
+  if (target()->holder()->is_subclass_of(field->holder())) {
+    if (target()->is_static()) {
+      if (target()->name() == ciSymbol::class_initializer_name()) {
+        // It's OK to access static fields from the class initializer
+        access_OK = true;
+      }
+    }
+    else {
+      if (target()->name() == ciSymbol::object_initializer_name()) {
+        // It's also OK to access static fields inside a constructor,
+        // because any thread calling the constructor must first have
+        // synchronized on the class by executing a "new" bytecode.
+        access_OK = true;
+      }
+    }
+  }
+  return access_OK;
+}
+
+SharkState* SharkTopLevelBlock::entry_state() {
+  if (_entry_state == NULL) {
+    assert(needs_phis(), "should do");
+    _entry_state = new SharkPHIState(this);
+  }
+  return _entry_state;
+}
+
+void SharkTopLevelBlock::add_incoming(SharkState* incoming_state) {
+  if (needs_phis()) {
+    ((SharkPHIState *) entry_state())->add_incoming(incoming_state);
+  }
+  else if (_entry_state == NULL) {
+    _entry_state = incoming_state;
+  }
+  else {
+    assert(entry_state()->equal_to(incoming_state), "should be");
+  }
+}
+
+void SharkTopLevelBlock::enter(SharkTopLevelBlock* predecessor,
+                               bool is_exception) {
+  // This block requires phis:
+  //  - if it is entered more than once
+  //  - if it is an exception handler, because in which
+  //    case we assume it's entered more than once.
+  //  - if the predecessor will be compiled after this
+  //    block, in which case we can't simple propagate
+  //    the state forward.
+  if (!needs_phis() &&
+      (entered() ||
+       is_exception ||
+       (predecessor && predecessor->index() >= index())))
+    _needs_phis = true;
+
+  // Recurse into the tree
+  if (!entered()) {
+    _entered = true;
+
+    scan_for_traps();
+    if (!has_trap()) {
+      for (int i = 0; i < num_successors(); i++) {
+        successor(i)->enter(this, false);
+      }
+    }
+    compute_exceptions();
+    for (int i = 0; i < num_exceptions(); i++) {
+      SharkTopLevelBlock *handler = exception(i);
+      if (handler)
+        handler->enter(this, true);
+    }
+  }
+}
+
+void SharkTopLevelBlock::initialize() {
+  char name[28];
+  snprintf(name, sizeof(name),
+           "bci_%d%s",
+           start(), is_backedge_copy() ? "_backedge_copy" : "");
+  _entry_block = function()->CreateBlock(name);
+}
+
+void SharkTopLevelBlock::decache_for_Java_call(ciMethod *callee) {
+  SharkJavaCallDecacher(function(), bci(), callee).scan(current_state());
+  for (int i = 0; i < callee->arg_size(); i++)
+    xpop();
+}
+
+void SharkTopLevelBlock::cache_after_Java_call(ciMethod *callee) {
+  if (callee->return_type()->size()) {
+    ciType *type;
+    switch (callee->return_type()->basic_type()) {
+    case T_BOOLEAN:
+    case T_BYTE:
+    case T_CHAR:
+    case T_SHORT:
+      type = ciType::make(T_INT);
+      break;
+
+    default:
+      type = callee->return_type();
+    }
+
+    push(SharkValue::create_generic(type, NULL, false));
+  }
+  SharkJavaCallCacher(function(), callee).scan(current_state());
+}
+
+void SharkTopLevelBlock::decache_for_VM_call() {
+  SharkVMCallDecacher(function(), bci()).scan(current_state());
+}
+
+void SharkTopLevelBlock::cache_after_VM_call() {
+  SharkVMCallCacher(function()).scan(current_state());
+}
+
+void SharkTopLevelBlock::decache_for_trap() {
+  SharkTrapDecacher(function(), bci()).scan(current_state());
+}
+
+void SharkTopLevelBlock::emit_IR() {
+  builder()->SetInsertPoint(entry_block());
+
+  // Parse the bytecode
+  parse_bytecode(start(), limit());
+
+  // If this block falls through to the next then it won't have been
+  // terminated by a bytecode and we have to add the branch ourselves
+  if (falls_through() && !has_trap())
+    do_branch(ciTypeFlow::FALL_THROUGH);
+}
+
+SharkTopLevelBlock* SharkTopLevelBlock::bci_successor(int bci) const {
+  // XXX now with Linear Search Technology (tm)
+  for (int i = 0; i < num_successors(); i++) {
+    ciTypeFlow::Block *successor = ciblock()->successors()->at(i);
+    if (successor->start() == bci)
+      return function()->block(successor->pre_order());
+  }
+  ShouldNotReachHere();
+}
+
+void SharkTopLevelBlock::do_zero_check(SharkValue *value) {
+  if (value->is_phi() && value->as_phi()->all_incomers_zero_checked()) {
+    function()->add_deferred_zero_check(this, value);
+  }
+  else {
+    BasicBlock *continue_block = function()->CreateBlock("not_zero");
+    SharkState *saved_state = current_state();
+    set_current_state(saved_state->copy());
+    zero_check_value(value, continue_block);
+    builder()->SetInsertPoint(continue_block);
+    set_current_state(saved_state);
+  }
+
+  value->set_zero_checked(true);
+}
+
+void SharkTopLevelBlock::do_deferred_zero_check(SharkValue* value,
+                                                int         bci,
+                                                SharkState* saved_state,
+                                                BasicBlock* continue_block) {
+  if (value->as_phi()->all_incomers_zero_checked()) {
+    builder()->CreateBr(continue_block);
+  }
+  else {
+    iter()->force_bci(start());
+    set_current_state(saved_state);
+    zero_check_value(value, continue_block);
+  }
+}
+
+void SharkTopLevelBlock::zero_check_value(SharkValue* value,
+                                          BasicBlock* continue_block) {
+  BasicBlock *zero_block = builder()->CreateBlock(continue_block, "zero");
+
+  Value *a, *b;
+  switch (value->basic_type()) {
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+  case T_INT:
+    a = value->jint_value();
+    b = LLVMValue::jint_constant(0);
+    break;
+  case T_LONG:
+    a = value->jlong_value();
+    b = LLVMValue::jlong_constant(0);
+    break;
+  case T_OBJECT:
+  case T_ARRAY:
+    a = value->jobject_value();
+    b = LLVMValue::LLVMValue::null();
+    break;
+  default:
+    tty->print_cr("Unhandled type %s", type2name(value->basic_type()));
+    ShouldNotReachHere();
+  }
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(a, b), continue_block, zero_block);
+
+  builder()->SetInsertPoint(zero_block);
+  if (value->is_jobject()) {
+    call_vm(
+      builder()->throw_NullPointerException(),
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) __FILE__),
+        PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jint_constant(__LINE__),
+      EX_CHECK_NONE);
+  }
+  else {
+    call_vm(
+      builder()->throw_ArithmeticException(),
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) __FILE__),
+        PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jint_constant(__LINE__),
+      EX_CHECK_NONE);
+  }
+
+  Value *pending_exception = get_pending_exception();
+  clear_pending_exception();
+  handle_exception(pending_exception, EX_CHECK_FULL);
+}
+
+void SharkTopLevelBlock::check_bounds(SharkValue* array, SharkValue* index) {
+  BasicBlock *out_of_bounds = function()->CreateBlock("out_of_bounds");
+  BasicBlock *in_bounds     = function()->CreateBlock("in_bounds");
+
+  Value *length = builder()->CreateArrayLength(array->jarray_value());
+  // we use an unsigned comparison to catch negative values
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(index->jint_value(), length),
+    in_bounds, out_of_bounds);
+
+  builder()->SetInsertPoint(out_of_bounds);
+  SharkState *saved_state = current_state()->copy();
+
+  call_vm(
+    builder()->throw_ArrayIndexOutOfBoundsException(),
+    builder()->CreateIntToPtr(
+      LLVMValue::intptr_constant((intptr_t) __FILE__),
+      PointerType::getUnqual(SharkType::jbyte_type())),
+    LLVMValue::jint_constant(__LINE__),
+    index->jint_value(),
+    EX_CHECK_NONE);
+
+  Value *pending_exception = get_pending_exception();
+  clear_pending_exception();
+  handle_exception(pending_exception, EX_CHECK_FULL);
+
+  set_current_state(saved_state);
+
+  builder()->SetInsertPoint(in_bounds);
+}
+
+void SharkTopLevelBlock::check_pending_exception(int action) {
+  assert(action & EAM_CHECK, "should be");
+
+  BasicBlock *exception    = function()->CreateBlock("exception");
+  BasicBlock *no_exception = function()->CreateBlock("no_exception");
+
+  Value *pending_exception = get_pending_exception();
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(pending_exception, LLVMValue::null()),
+    no_exception, exception);
+
+  builder()->SetInsertPoint(exception);
+  SharkState *saved_state = current_state()->copy();
+  if (action & EAM_MONITOR_FUDGE) {
+    // The top monitor is marked live, but the exception was thrown
+    // while setting it up so we need to mark it dead before we enter
+    // any exception handlers as they will not expect it to be there.
+    set_num_monitors(num_monitors() - 1);
+    action ^= EAM_MONITOR_FUDGE;
+  }
+  clear_pending_exception();
+  handle_exception(pending_exception, action);
+  set_current_state(saved_state);
+
+  builder()->SetInsertPoint(no_exception);
+}
+
+void SharkTopLevelBlock::compute_exceptions() {
+  ciExceptionHandlerStream str(target(), start());
+
+  int exc_count = str.count();
+  _exc_handlers = new GrowableArray<ciExceptionHandler*>(exc_count);
+  _exceptions   = new GrowableArray<SharkTopLevelBlock*>(exc_count);
+
+  int index = 0;
+  for (; !str.is_done(); str.next()) {
+    ciExceptionHandler *handler = str.handler();
+    if (handler->handler_bci() == -1)
+      break;
+    _exc_handlers->append(handler);
+
+    // Try and get this exception's handler from typeflow.  We should
+    // do it this way always, really, except that typeflow sometimes
+    // doesn't record exceptions, even loaded ones, and sometimes it
+    // returns them with a different handler bci.  Why???
+    SharkTopLevelBlock *block = NULL;
+    ciInstanceKlass* klass;
+    if (handler->is_catch_all()) {
+      klass = java_lang_Throwable_klass();
+    }
+    else {
+      klass = handler->catch_klass();
+    }
+    for (int i = 0; i < ciblock()->exceptions()->length(); i++) {
+      if (klass == ciblock()->exc_klasses()->at(i)) {
+        block = function()->block(ciblock()->exceptions()->at(i)->pre_order());
+        if (block->start() == handler->handler_bci())
+          break;
+        else
+          block = NULL;
+      }
+    }
+
+    // If typeflow let us down then try and figure it out ourselves
+    if (block == NULL) {
+      for (int i = 0; i < function()->block_count(); i++) {
+        SharkTopLevelBlock *candidate = function()->block(i);
+        if (candidate->start() == handler->handler_bci()) {
+          if (block != NULL) {
+            NOT_PRODUCT(warning("there may be trouble ahead"));
+            block = NULL;
+            break;
+          }
+          block = candidate;
+        }
+      }
+    }
+    _exceptions->append(block);
+  }
+}
+
+void SharkTopLevelBlock::handle_exception(Value* exception, int action) {
+  if (action & EAM_HANDLE && num_exceptions() != 0) {
+    // Clear the stack and push the exception onto it
+    while (xstack_depth())
+      pop();
+    push(SharkValue::create_jobject(exception, true));
+
+    // Work out how many options we have to check
+    bool has_catch_all = exc_handler(num_exceptions() - 1)->is_catch_all();
+    int num_options = num_exceptions();
+    if (has_catch_all)
+      num_options--;
+
+    // Marshal any non-catch-all handlers
+    if (num_options > 0) {
+      bool all_loaded = true;
+      for (int i = 0; i < num_options; i++) {
+        if (!exc_handler(i)->catch_klass()->is_loaded()) {
+          all_loaded = false;
+          break;
+        }
+      }
+
+      if (all_loaded)
+        marshal_exception_fast(num_options);
+      else
+        marshal_exception_slow(num_options);
+    }
+
+    // Install the catch-all handler, if present
+    if (has_catch_all) {
+      SharkTopLevelBlock* handler = this->exception(num_options);
+      assert(handler != NULL, "catch-all handler cannot be unloaded");
+
+      builder()->CreateBr(handler->entry_block());
+      handler->add_incoming(current_state());
+      return;
+    }
+  }
+
+  // No exception handler was found; unwind and return
+  handle_return(T_VOID, exception);
+}
+
+void SharkTopLevelBlock::marshal_exception_fast(int num_options) {
+  Value *exception_klass = builder()->CreateValueOfStructEntry(
+    xstack(0)->jobject_value(),
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "exception_klass");
+
+  for (int i = 0; i < num_options; i++) {
+    Value *check_klass =
+      builder()->CreateInlineOop(exc_handler(i)->catch_klass());
+
+    BasicBlock *not_exact   = function()->CreateBlock("not_exact");
+    BasicBlock *not_subtype = function()->CreateBlock("not_subtype");
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpEQ(check_klass, exception_klass),
+      handler_for_exception(i), not_exact);
+
+    builder()->SetInsertPoint(not_exact);
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(
+        builder()->CreateCall2(
+          builder()->is_subtype_of(), check_klass, exception_klass),
+        LLVMValue::jbyte_constant(0)),
+      handler_for_exception(i), not_subtype);
+
+    builder()->SetInsertPoint(not_subtype);
+  }
+}
+
+void SharkTopLevelBlock::marshal_exception_slow(int num_options) {
+  int *indexes = NEW_RESOURCE_ARRAY(int, num_options);
+  for (int i = 0; i < num_options; i++)
+    indexes[i] = exc_handler(i)->catch_klass_index();
+
+  Value *index = call_vm(
+    builder()->find_exception_handler(),
+    builder()->CreateInlineData(
+      indexes,
+      num_options * sizeof(int),
+      PointerType::getUnqual(SharkType::jint_type())),
+    LLVMValue::jint_constant(num_options),
+    EX_CHECK_NO_CATCH);
+
+  BasicBlock *no_handler = function()->CreateBlock("no_handler");
+  SwitchInst *switchinst = builder()->CreateSwitch(
+    index, no_handler, num_options);
+
+  for (int i = 0; i < num_options; i++) {
+    switchinst->addCase(
+      LLVMValue::jint_constant(i),
+      handler_for_exception(i));
+  }
+
+  builder()->SetInsertPoint(no_handler);
+}
+
+BasicBlock* SharkTopLevelBlock::handler_for_exception(int index) {
+  SharkTopLevelBlock *successor = this->exception(index);
+  if (successor) {
+    successor->add_incoming(current_state());
+    return successor->entry_block();
+  }
+  else {
+    return make_trap(
+      exc_handler(index)->handler_bci(),
+      Deoptimization::make_trap_request(
+        Deoptimization::Reason_unhandled,
+        Deoptimization::Action_reinterpret));
+  }
+}
+
+void SharkTopLevelBlock::maybe_add_safepoint() {
+  if (current_state()->has_safepointed())
+    return;
+
+  BasicBlock *orig_block = builder()->GetInsertBlock();
+  SharkState *orig_state = current_state()->copy();
+
+  BasicBlock *do_safepoint = function()->CreateBlock("do_safepoint");
+  BasicBlock *safepointed  = function()->CreateBlock("safepointed");
+
+  Value *state = builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      LLVMValue::intptr_constant(
+        (intptr_t) SafepointSynchronize::address_of_state()),
+      PointerType::getUnqual(SharkType::jint_type())),
+    "state");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      state,
+      LLVMValue::jint_constant(SafepointSynchronize::_synchronizing)),
+    do_safepoint, safepointed);
+
+  builder()->SetInsertPoint(do_safepoint);
+  call_vm(builder()->safepoint(), EX_CHECK_FULL);
+  BasicBlock *safepointed_block = builder()->GetInsertBlock();
+  builder()->CreateBr(safepointed);
+
+  builder()->SetInsertPoint(safepointed);
+  current_state()->merge(orig_state, orig_block, safepointed_block);
+
+  current_state()->set_has_safepointed(true);
+}
+
+void SharkTopLevelBlock::maybe_add_backedge_safepoint() {
+  if (current_state()->has_safepointed())
+    return;
+
+  for (int i = 0; i < num_successors(); i++) {
+    if (successor(i)->can_reach(this)) {
+      maybe_add_safepoint();
+      break;
+    }
+  }
+}
+
+bool SharkTopLevelBlock::can_reach(SharkTopLevelBlock* other) {
+  for (int i = 0; i < function()->block_count(); i++)
+    function()->block(i)->_can_reach_visited = false;
+
+  return can_reach_helper(other);
+}
+
+bool SharkTopLevelBlock::can_reach_helper(SharkTopLevelBlock* other) {
+  if (this == other)
+    return true;
+
+  if (_can_reach_visited)
+    return false;
+  _can_reach_visited = true;
+
+  if (!has_trap()) {
+    for (int i = 0; i < num_successors(); i++) {
+      if (successor(i)->can_reach_helper(other))
+        return true;
+    }
+  }
+
+  for (int i = 0; i < num_exceptions(); i++) {
+    SharkTopLevelBlock *handler = exception(i);
+    if (handler && handler->can_reach_helper(other))
+      return true;
+  }
+
+  return false;
+}
+
+BasicBlock* SharkTopLevelBlock::make_trap(int trap_bci, int trap_request) {
+  BasicBlock *trap_block = function()->CreateBlock("trap");
+  BasicBlock *orig_block = builder()->GetInsertBlock();
+  builder()->SetInsertPoint(trap_block);
+
+  int orig_bci = bci();
+  iter()->force_bci(trap_bci);
+
+  do_trap(trap_request);
+
+  builder()->SetInsertPoint(orig_block);
+  iter()->force_bci(orig_bci);
+
+  return trap_block;
+}
+
+void SharkTopLevelBlock::do_trap(int trap_request) {
+  decache_for_trap();
+  builder()->CreateRet(
+    builder()->CreateCall2(
+      builder()->uncommon_trap(),
+      thread(),
+      LLVMValue::jint_constant(trap_request)));
+}
+
+void SharkTopLevelBlock::call_register_finalizer(Value *receiver) {
+  BasicBlock *orig_block = builder()->GetInsertBlock();
+  SharkState *orig_state = current_state()->copy();
+
+  BasicBlock *do_call = function()->CreateBlock("has_finalizer");
+  BasicBlock *done    = function()->CreateBlock("done");
+
+  Value *klass = builder()->CreateValueOfStructEntry(
+    receiver,
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "klass");
+
+  Value *klass_part = builder()->CreateAddressOfStructEntry(
+    klass,
+    in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()),
+    SharkType::klass_type(),
+    "klass_part");
+
+  Value *access_flags = builder()->CreateValueOfStructEntry(
+    klass_part,
+    in_ByteSize(Klass::access_flags_offset_in_bytes()),
+    SharkType::jint_type(),
+    "access_flags");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      builder()->CreateAnd(
+        access_flags,
+        LLVMValue::jint_constant(JVM_ACC_HAS_FINALIZER)),
+      LLVMValue::jint_constant(0)),
+    do_call, done);
+
+  builder()->SetInsertPoint(do_call);
+  call_vm(builder()->register_finalizer(), receiver, EX_CHECK_FULL);
+  BasicBlock *branch_block = builder()->GetInsertBlock();
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  current_state()->merge(orig_state, orig_block, branch_block);
+}
+
+void SharkTopLevelBlock::handle_return(BasicType type, Value* exception) {
+  assert (exception == NULL || type == T_VOID, "exception OR result, please");
+
+  if (num_monitors()) {
+    // Protect our exception across possible monitor release decaches
+    if (exception)
+      set_oop_tmp(exception);
+
+    // We don't need to check for exceptions thrown here.  If
+    // we're returning a value then we just carry on as normal:
+    // the caller will see the pending exception and handle it.
+    // If we're returning with an exception then that exception
+    // takes priority and the release_lock one will be ignored.
+    while (num_monitors())
+      release_lock(EX_CHECK_NONE);
+
+    // Reload the exception we're throwing
+    if (exception)
+      exception = get_oop_tmp();
+  }
+
+  if (exception) {
+    builder()->CreateStore(exception, pending_exception_address());
+  }
+
+  Value *result_addr = stack()->CreatePopFrame(type2size[type]);
+  if (type != T_VOID) {
+    builder()->CreateStore(
+      pop_result(type)->generic_value(),
+      builder()->CreateIntToPtr(
+        result_addr,
+        PointerType::getUnqual(SharkType::to_stackType(type))));
+  }
+
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+}
+
+void SharkTopLevelBlock::do_arraylength() {
+  SharkValue *array = pop();
+  check_null(array);
+  Value *length = builder()->CreateArrayLength(array->jarray_value());
+  push(SharkValue::create_jint(length, false));
+}
+
+void SharkTopLevelBlock::do_aload(BasicType basic_type) {
+  SharkValue *index = pop();
+  SharkValue *array = pop();
+
+  check_null(array);
+  check_bounds(array, index);
+
+  Value *value = builder()->CreateLoad(
+    builder()->CreateArrayAddress(
+      array->jarray_value(), basic_type, index->jint_value()));
+
+  const Type *stack_type = SharkType::to_stackType(basic_type);
+  if (value->getType() != stack_type)
+    value = builder()->CreateIntCast(value, stack_type, basic_type != T_CHAR);
+
+  switch (basic_type) {
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+  case T_INT:
+    push(SharkValue::create_jint(value, false));
+    break;
+
+  case T_LONG:
+    push(SharkValue::create_jlong(value, false));
+    break;
+
+  case T_FLOAT:
+    push(SharkValue::create_jfloat(value));
+    break;
+
+  case T_DOUBLE:
+    push(SharkValue::create_jdouble(value));
+    break;
+
+  case T_OBJECT:
+    // You might expect that array->type()->is_array_klass() would
+    // always be true, but it isn't.  If ciTypeFlow detects that a
+    // value is always null then that value becomes an untyped null
+    // object.  Shark doesn't presently support this, so a generic
+    // T_OBJECT is created.  In this case we guess the type using
+    // the BasicType we were supplied.  In reality the generated
+    // code will never be used, as the null value will be caught
+    // by the above null pointer check.
+    // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=324
+    push(
+      SharkValue::create_generic(
+        array->type()->is_array_klass() ?
+          ((ciArrayKlass *) array->type())->element_type() :
+          ciType::make(basic_type),
+        value, false));
+    break;
+
+  default:
+    tty->print_cr("Unhandled type %s", type2name(basic_type));
+    ShouldNotReachHere();
+  }
+}
+
+void SharkTopLevelBlock::do_astore(BasicType basic_type) {
+  SharkValue *svalue = pop();
+  SharkValue *index  = pop();
+  SharkValue *array  = pop();
+
+  check_null(array);
+  check_bounds(array, index);
+
+  Value *value;
+  switch (basic_type) {
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+  case T_INT:
+    value = svalue->jint_value();
+    break;
+
+  case T_LONG:
+    value = svalue->jlong_value();
+    break;
+
+  case T_FLOAT:
+    value = svalue->jfloat_value();
+    break;
+
+  case T_DOUBLE:
+    value = svalue->jdouble_value();
+    break;
+
+  case T_OBJECT:
+    value = svalue->jobject_value();
+    // XXX assignability check
+    break;
+
+  default:
+    tty->print_cr("Unhandled type %s", type2name(basic_type));
+    ShouldNotReachHere();
+  }
+
+  const Type *array_type = SharkType::to_arrayType(basic_type);
+  if (value->getType() != array_type)
+    value = builder()->CreateIntCast(value, array_type, basic_type != T_CHAR);
+
+  Value *addr = builder()->CreateArrayAddress(
+    array->jarray_value(), basic_type, index->jint_value(), "addr");
+
+  builder()->CreateStore(value, addr);
+
+  if (basic_type == T_OBJECT) // XXX or T_ARRAY?
+    builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
+}
+
+void SharkTopLevelBlock::do_return(BasicType type) {
+  if (target()->intrinsic_id() == vmIntrinsics::_Object_init)
+    call_register_finalizer(local(0)->jobject_value());
+  maybe_add_safepoint();
+  handle_return(type, NULL);
+}
+
+void SharkTopLevelBlock::do_athrow() {
+  SharkValue *exception = pop();
+  check_null(exception);
+  handle_exception(exception->jobject_value(), EX_CHECK_FULL);
+}
+
+void SharkTopLevelBlock::do_goto() {
+  do_branch(ciTypeFlow::GOTO_TARGET);
+}
+
+void SharkTopLevelBlock::do_jsr() {
+  push(SharkValue::address_constant(iter()->next_bci()));
+  do_branch(ciTypeFlow::GOTO_TARGET);
+}
+
+void SharkTopLevelBlock::do_ret() {
+  assert(local(iter()->get_index())->address_value() ==
+         successor(ciTypeFlow::GOTO_TARGET)->start(), "should be");
+  do_branch(ciTypeFlow::GOTO_TARGET);
+}
+
+// All propagation of state from one block to the next (via
+// dest->add_incoming) is handled by these methods:
+//   do_branch
+//   do_if_helper
+//   do_switch
+//   handle_exception
+
+void SharkTopLevelBlock::do_branch(int successor_index) {
+  SharkTopLevelBlock *dest = successor(successor_index);
+  builder()->CreateBr(dest->entry_block());
+  dest->add_incoming(current_state());
+}
+
+void SharkTopLevelBlock::do_if(ICmpInst::Predicate p,
+                               SharkValue*         b,
+                               SharkValue*         a) {
+  Value *llvm_a, *llvm_b;
+  if (a->is_jobject()) {
+    llvm_a = a->intptr_value(builder());
+    llvm_b = b->intptr_value(builder());
+  }
+  else {
+    llvm_a = a->jint_value();
+    llvm_b = b->jint_value();
+  }
+  do_if_helper(p, llvm_b, llvm_a, current_state(), current_state());
+}
+
+void SharkTopLevelBlock::do_if_helper(ICmpInst::Predicate p,
+                                      Value*              b,
+                                      Value*              a,
+                                      SharkState*         if_taken_state,
+                                      SharkState*         not_taken_state) {
+  SharkTopLevelBlock *if_taken  = successor(ciTypeFlow::IF_TAKEN);
+  SharkTopLevelBlock *not_taken = successor(ciTypeFlow::IF_NOT_TAKEN);
+
+  builder()->CreateCondBr(
+    builder()->CreateICmp(p, a, b),
+    if_taken->entry_block(), not_taken->entry_block());
+
+  if_taken->add_incoming(if_taken_state);
+  not_taken->add_incoming(not_taken_state);
+}
+
+void SharkTopLevelBlock::do_switch() {
+  int len = switch_table_length();
+
+  SharkTopLevelBlock *dest_block = successor(ciTypeFlow::SWITCH_DEFAULT);
+  SwitchInst *switchinst = builder()->CreateSwitch(
+    pop()->jint_value(), dest_block->entry_block(), len);
+  dest_block->add_incoming(current_state());
+
+  for (int i = 0; i < len; i++) {
+    int dest_bci = switch_dest(i);
+    if (dest_bci != switch_default_dest()) {
+      dest_block = bci_successor(dest_bci);
+      switchinst->addCase(
+        LLVMValue::jint_constant(switch_key(i)),
+        dest_block->entry_block());
+      dest_block->add_incoming(current_state());
+    }
+  }
+}
+
+ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod*   caller,
+                                              ciInstanceKlass* klass,
+                                              ciMethod*        dest_method,
+                                              ciType*          receiver_type) {
+  // If the method is obviously final then we are already done
+  if (dest_method->can_be_statically_bound())
+    return dest_method;
+
+  // Array methods are all inherited from Object and are monomorphic
+  if (receiver_type->is_array_klass() &&
+      dest_method->holder() == java_lang_Object_klass())
+    return dest_method;
+
+#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE
+  // This code can replace a virtual call with a direct call if this
+  // class is the only one in the entire set of loaded classes that
+  // implements this method.  This makes the compiled code dependent
+  // on other classes that implement the method not being loaded, a
+  // condition which is enforced by the dependency tracker.  If the
+  // dependency tracker determines a method has become invalid it
+  // will mark it for recompilation, causing running copies to be
+  // deoptimized.  Shark currently can't deoptimize arbitrarily like
+  // that, so this optimization cannot be used.
+  // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=481
+
+  // All other interesting cases are instance classes
+  if (!receiver_type->is_instance_klass())
+    return NULL;
+
+  // Attempt to improve the receiver
+  ciInstanceKlass* actual_receiver = klass;
+  ciInstanceKlass *improved_receiver = receiver_type->as_instance_klass();
+  if (improved_receiver->is_loaded() &&
+      improved_receiver->is_initialized() &&
+      !improved_receiver->is_interface() &&
+      improved_receiver->is_subtype_of(actual_receiver)) {
+    actual_receiver = improved_receiver;
+  }
+
+  // Attempt to find a monomorphic target for this call using
+  // class heirachy analysis.
+  ciInstanceKlass *calling_klass = caller->holder();
+  ciMethod* monomorphic_target =
+    dest_method->find_monomorphic_target(calling_klass, klass, actual_receiver);
+  if (monomorphic_target != NULL) {
+    assert(!monomorphic_target->is_abstract(), "shouldn't be");
+
+    // Opto has a bunch of type checking here that I don't
+    // understand.  It's to inhibit casting in one direction,
+    // possibly because objects in Opto can have inexact
+    // types, but I can't even tell which direction it
+    // doesn't like.  For now I'm going to block *any* cast.
+    if (monomorphic_target != dest_method) {
+      if (SharkPerformanceWarnings) {
+        warning("found monomorphic target, but inhibited cast:");
+        tty->print("  dest_method = ");
+        dest_method->print_short_name(tty);
+        tty->cr();
+        tty->print("  monomorphic_target = ");
+        monomorphic_target->print_short_name(tty);
+        tty->cr();
+      }
+      monomorphic_target = NULL;
+    }
+  }
+
+  // Replace the virtual call with a direct one.  This makes
+  // us dependent on that target method not getting overridden
+  // by dynamic class loading.
+  if (monomorphic_target != NULL) {
+    dependencies()->assert_unique_concrete_method(
+      actual_receiver, monomorphic_target);
+    return monomorphic_target;
+  }
+
+  // Because Opto distinguishes exact types from inexact ones
+  // it can perform a further optimization to replace calls
+  // with non-monomorphic targets if the receiver has an exact
+  // type.  We don't mark types this way, so we can't do this.
+
+#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE
+
+  return NULL;
+}
+
+Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) {
+  return builder()->CreateBitCast(
+    builder()->CreateInlineOop(method),
+    SharkType::methodOop_type(),
+    "callee");
+}
+
+Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver,
+                                              int vtable_index) {
+  Value *klass = builder()->CreateValueOfStructEntry(
+    receiver->jobject_value(),
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "klass");
+
+  return builder()->CreateLoad(
+    builder()->CreateArrayAddress(
+      klass,
+      SharkType::methodOop_type(),
+      vtableEntry::size() * wordSize,
+      in_ByteSize(instanceKlass::vtable_start_offset() * wordSize),
+      LLVMValue::intptr_constant(vtable_index)),
+    "callee");
+}
+
+Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver,
+                                                ciMethod*   method) {
+  BasicBlock *loop       = function()->CreateBlock("loop");
+  BasicBlock *got_null   = function()->CreateBlock("got_null");
+  BasicBlock *not_null   = function()->CreateBlock("not_null");
+  BasicBlock *next       = function()->CreateBlock("next");
+  BasicBlock *got_entry  = function()->CreateBlock("got_entry");
+
+  // Locate the receiver's itable
+  Value *object_klass = builder()->CreateValueOfStructEntry(
+    receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "object_klass");
+
+  Value *vtable_start = builder()->CreateAdd(
+    builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
+    LLVMValue::intptr_constant(
+      instanceKlass::vtable_start_offset() * HeapWordSize),
+    "vtable_start");
+
+  Value *vtable_length = builder()->CreateValueOfStructEntry(
+    object_klass,
+    in_ByteSize(instanceKlass::vtable_length_offset() * HeapWordSize),
+    SharkType::jint_type(),
+    "vtable_length");
+  vtable_length =
+    builder()->CreateIntCast(vtable_length, SharkType::intptr_type(), false);
+
+  bool needs_aligning = HeapWordsPerLong > 1;
+  Value *itable_start = builder()->CreateAdd(
+    vtable_start,
+    builder()->CreateShl(
+      vtable_length,
+      LLVMValue::intptr_constant(exact_log2(vtableEntry::size() * wordSize))),
+    needs_aligning ? "" : "itable_start");
+  if (needs_aligning) {
+    itable_start = builder()->CreateAnd(
+      builder()->CreateAdd(
+        itable_start, LLVMValue::intptr_constant(BytesPerLong - 1)),
+      LLVMValue::intptr_constant(~(BytesPerLong - 1)),
+      "itable_start");
+  }
+
+  // Locate this interface's entry in the table
+  Value *iklass = builder()->CreateInlineOop(method->holder());
+  BasicBlock *loop_entry = builder()->GetInsertBlock();
+  builder()->CreateBr(loop);
+  builder()->SetInsertPoint(loop);
+  PHINode *itable_entry_addr = builder()->CreatePHI(
+    SharkType::intptr_type(), "itable_entry_addr");
+  itable_entry_addr->addIncoming(itable_start, loop_entry);
+
+  Value *itable_entry = builder()->CreateIntToPtr(
+    itable_entry_addr, SharkType::itableOffsetEntry_type(), "itable_entry");
+
+  Value *itable_iklass = builder()->CreateValueOfStructEntry(
+    itable_entry,
+    in_ByteSize(itableOffsetEntry::interface_offset_in_bytes()),
+    SharkType::oop_type(),
+    "itable_iklass");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(itable_iklass, LLVMValue::null()),
+    got_null, not_null);
+
+  // A null entry means that the class doesn't implement the
+  // interface, and wasn't the same as the class checked when
+  // the interface was resolved.
+  builder()->SetInsertPoint(got_null);
+  builder()->CreateUnimplemented(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  builder()->SetInsertPoint(not_null);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(itable_iklass, iklass),
+    got_entry, next);
+
+  builder()->SetInsertPoint(next);
+  Value *next_entry = builder()->CreateAdd(
+    itable_entry_addr,
+    LLVMValue::intptr_constant(itableOffsetEntry::size() * wordSize));
+  builder()->CreateBr(loop);
+  itable_entry_addr->addIncoming(next_entry, next);
+
+  // Locate the method pointer
+  builder()->SetInsertPoint(got_entry);
+  Value *offset = builder()->CreateValueOfStructEntry(
+    itable_entry,
+    in_ByteSize(itableOffsetEntry::offset_offset_in_bytes()),
+    SharkType::jint_type(),
+    "offset");
+  offset =
+    builder()->CreateIntCast(offset, SharkType::intptr_type(), false);
+
+  return builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      builder()->CreateAdd(
+        builder()->CreateAdd(
+          builder()->CreateAdd(
+            builder()->CreatePtrToInt(
+              object_klass, SharkType::intptr_type()),
+            offset),
+          LLVMValue::intptr_constant(
+            method->itable_index() * itableMethodEntry::size() * wordSize)),
+        LLVMValue::intptr_constant(
+          itableMethodEntry::method_offset_in_bytes())),
+      PointerType::getUnqual(SharkType::methodOop_type())),
+    "callee");
+}
+
+void SharkTopLevelBlock::do_call() {
+  // Set frequently used booleans
+  bool is_static = bc() == Bytecodes::_invokestatic;
+  bool is_virtual = bc() == Bytecodes::_invokevirtual;
+  bool is_interface = bc() == Bytecodes::_invokeinterface;
+
+  // Find the method being called
+  bool will_link;
+  ciMethod *dest_method = iter()->get_method(will_link);
+  assert(will_link, "typeflow responsibility");
+  assert(dest_method->is_static() == is_static, "must match bc");
+
+  // Find the class of the method being called.  Note
+  // that the superclass check in the second assertion
+  // is to cope with a hole in the spec that allows for
+  // invokeinterface instructions where the resolved
+  // method is a virtual method in java.lang.Object.
+  // javac doesn't generate code like that, but there's
+  // no reason a compliant Java compiler might not.
+  ciInstanceKlass *holder_klass  = dest_method->holder();
+  assert(holder_klass->is_loaded(), "scan_for_traps responsibility");
+  assert(holder_klass->is_interface() ||
+         holder_klass->super() == NULL ||
+         !is_interface, "must match bc");
+  ciKlass *holder = iter()->get_declared_method_holder();
+  ciInstanceKlass *klass =
+    ciEnv::get_instance_klass_for_declared_method_holder(holder);
+
+  // Find the receiver in the stack.  We do this before
+  // trying to inline because the inliner can only use
+  // zero-checked values, not being able to perform the
+  // check itself.
+  SharkValue *receiver = NULL;
+  if (!is_static) {
+    receiver = xstack(dest_method->arg_size() - 1);
+    check_null(receiver);
+  }
+
+  // Try to improve non-direct calls
+  bool call_is_virtual = is_virtual || is_interface;
+  ciMethod *call_method = dest_method;
+  if (call_is_virtual) {
+    ciMethod *optimized_method = improve_virtual_call(
+      target(), klass, dest_method, receiver->type());
+    if (optimized_method) {
+      call_method = optimized_method;
+      call_is_virtual = false;
+    }
+  }
+
+  // Try to inline the call
+  if (!call_is_virtual) {
+    if (SharkInliner::attempt_inline(call_method, current_state()))
+      return;
+  }
+
+  // Find the method we are calling
+  Value *callee;
+  if (call_is_virtual) {
+    if (is_virtual) {
+      assert(klass->is_linked(), "scan_for_traps responsibility");
+      int vtable_index = call_method->resolve_vtable_index(
+        target()->holder(), klass);
+      assert(vtable_index >= 0, "should be");
+      callee = get_virtual_callee(receiver, vtable_index);
+    }
+    else {
+      assert(is_interface, "should be");
+      callee = get_interface_callee(receiver, call_method);
+    }
+  }
+  else {
+    callee = get_direct_callee(call_method);
+  }
+
+  // Load the SharkEntry from the callee
+  Value *base_pc = builder()->CreateValueOfStructEntry(
+    callee, methodOopDesc::from_interpreted_offset(),
+    SharkType::intptr_type(),
+    "base_pc");
+
+  // Load the entry point from the SharkEntry
+  Value *entry_point = builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      builder()->CreateAdd(
+        base_pc,
+        LLVMValue::intptr_constant(in_bytes(ZeroEntry::entry_point_offset()))),
+      PointerType::getUnqual(
+        PointerType::getUnqual(SharkType::entry_point_type()))),
+    "entry_point");
+
+  // Make the call
+  decache_for_Java_call(call_method);
+  Value *deoptimized_frames = builder()->CreateCall3(
+    entry_point, callee, base_pc, thread());
+
+  // If the callee got deoptimized then reexecute in the interpreter
+  BasicBlock *reexecute      = function()->CreateBlock("reexecute");
+  BasicBlock *call_completed = function()->CreateBlock("call_completed");
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(deoptimized_frames, LLVMValue::jint_constant(0)),
+    reexecute, call_completed);
+
+  builder()->SetInsertPoint(reexecute);
+  builder()->CreateCall2(
+    builder()->deoptimized_entry_point(),
+    builder()->CreateSub(deoptimized_frames, LLVMValue::jint_constant(1)),
+    thread());
+  builder()->CreateBr(call_completed);
+
+  // Cache after the call
+  builder()->SetInsertPoint(call_completed);
+  cache_after_Java_call(call_method);
+
+  // Check for pending exceptions
+  check_pending_exception(EX_CHECK_FULL);
+
+  // Mark that a safepoint check has occurred
+  current_state()->set_has_safepointed(true);
+}
+
+bool SharkTopLevelBlock::static_subtype_check(ciKlass* check_klass,
+                                              ciKlass* object_klass) {
+  // If the class we're checking against is java.lang.Object
+  // then this is a no brainer.  Apparently this can happen
+  // in reflective code...
+  if (check_klass == java_lang_Object_klass())
+    return true;
+
+  // Perform a subtype check.  NB in opto's code for this
+  // (GraphKit::static_subtype_check) it says that static
+  // interface types cannot be trusted, and if opto can't
+  // trust them then I assume we can't either.
+  if (object_klass->is_loaded() && !object_klass->is_interface()) {
+    if (object_klass == check_klass)
+      return true;
+
+    if (check_klass->is_loaded() && object_klass->is_subtype_of(check_klass))
+      return true;
+  }
+
+  return false;
+}
+
+void SharkTopLevelBlock::do_instance_check() {
+  // Get the class we're checking against
+  bool will_link;
+  ciKlass *check_klass = iter()->get_klass(will_link);
+
+  // Get the class of the object we're checking
+  ciKlass *object_klass = xstack(0)->type()->as_klass();
+
+  // Can we optimize this check away?
+  if (static_subtype_check(check_klass, object_klass)) {
+    if (bc() == Bytecodes::_instanceof) {
+      pop();
+      push(SharkValue::jint_constant(1));
+    }
+    return;
+  }
+
+  // Need to check this one at runtime
+  if (will_link)
+    do_full_instance_check(check_klass);
+  else
+    do_trapping_instance_check(check_klass);
+}
+
+bool SharkTopLevelBlock::maybe_do_instanceof_if() {
+  // Get the class we're checking against
+  bool will_link;
+  ciKlass *check_klass = iter()->get_klass(will_link);
+
+  // If the class is unloaded then the instanceof
+  // cannot possibly succeed.
+  if (!will_link)
+    return false;
+
+  // Keep a copy of the object we're checking
+  SharkValue *old_object = xstack(0);
+
+  // Get the class of the object we're checking
+  ciKlass *object_klass = old_object->type()->as_klass();
+
+  // If the instanceof can be optimized away at compile time
+  // then any subsequent checkcasts will be too so we handle
+  // it normally.
+  if (static_subtype_check(check_klass, object_klass))
+    return false;
+
+  // Perform the instance check
+  do_full_instance_check(check_klass);
+  Value *result = pop()->jint_value();
+
+  // Create the casted object
+  SharkValue *new_object = SharkValue::create_generic(
+    check_klass, old_object->jobject_value(), old_object->zero_checked());
+
+  // Create two copies of the current state, one with the
+  // original object and one with all instances of the
+  // original object replaced with the new, casted object.
+  SharkState *new_state = current_state();
+  SharkState *old_state = new_state->copy();
+  new_state->replace_all(old_object, new_object);
+
+  // Perform the check-and-branch
+  switch (iter()->next_bc()) {
+  case Bytecodes::_ifeq:
+    // branch if not an instance
+    do_if_helper(
+      ICmpInst::ICMP_EQ,
+      LLVMValue::jint_constant(0), result,
+      old_state, new_state);
+    break;
+
+  case Bytecodes::_ifne:
+    // branch if an instance
+    do_if_helper(
+      ICmpInst::ICMP_NE,
+      LLVMValue::jint_constant(0), result,
+      new_state, old_state);
+    break;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return true;
+}
+
+void SharkTopLevelBlock::do_full_instance_check(ciKlass* klass) {
+  BasicBlock *not_null      = function()->CreateBlock("not_null");
+  BasicBlock *subtype_check = function()->CreateBlock("subtype_check");
+  BasicBlock *is_instance   = function()->CreateBlock("is_instance");
+  BasicBlock *not_instance  = function()->CreateBlock("not_instance");
+  BasicBlock *merge1        = function()->CreateBlock("merge1");
+  BasicBlock *merge2        = function()->CreateBlock("merge2");
+
+  enum InstanceCheckStates {
+    IC_IS_NULL,
+    IC_IS_INSTANCE,
+    IC_NOT_INSTANCE,
+  };
+
+  // Pop the object off the stack
+  Value *object = pop()->jobject_value();
+
+  // Null objects aren't instances of anything
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(object, LLVMValue::null()),
+    merge2, not_null);
+  BasicBlock *null_block = builder()->GetInsertBlock();
+
+  // Get the class we're checking against
+  builder()->SetInsertPoint(not_null);
+  Value *check_klass = builder()->CreateInlineOop(klass);
+
+  // Get the class of the object being tested
+  Value *object_klass = builder()->CreateValueOfStructEntry(
+    object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "object_klass");
+
+  // Perform the check
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(check_klass, object_klass),
+    is_instance, subtype_check);
+
+  builder()->SetInsertPoint(subtype_check);
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      builder()->CreateCall2(
+        builder()->is_subtype_of(), check_klass, object_klass),
+      LLVMValue::jbyte_constant(0)),
+    is_instance, not_instance);
+
+  builder()->SetInsertPoint(is_instance);
+  builder()->CreateBr(merge1);
+
+  builder()->SetInsertPoint(not_instance);
+  builder()->CreateBr(merge1);
+
+  // First merge
+  builder()->SetInsertPoint(merge1);
+  PHINode *nonnull_result = builder()->CreatePHI(
+    SharkType::jint_type(), "nonnull_result");
+  nonnull_result->addIncoming(
+    LLVMValue::jint_constant(IC_IS_INSTANCE), is_instance);
+  nonnull_result->addIncoming(
+    LLVMValue::jint_constant(IC_NOT_INSTANCE), not_instance);
+  BasicBlock *nonnull_block = builder()->GetInsertBlock();
+  builder()->CreateBr(merge2);
+
+  // Second merge
+  builder()->SetInsertPoint(merge2);
+  PHINode *result = builder()->CreatePHI(
+    SharkType::jint_type(), "result");
+  result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block);
+  result->addIncoming(nonnull_result, nonnull_block);
+
+  // Handle the result
+  if (bc() == Bytecodes::_checkcast) {
+    BasicBlock *failure = function()->CreateBlock("failure");
+    BasicBlock *success = function()->CreateBlock("success");
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(
+        result, LLVMValue::jint_constant(IC_NOT_INSTANCE)),
+      success, failure);
+
+    builder()->SetInsertPoint(failure);
+    SharkState *saved_state = current_state()->copy();
+
+    call_vm(
+      builder()->throw_ClassCastException(),
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) __FILE__),
+        PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jint_constant(__LINE__),
+      EX_CHECK_NONE);
+
+    Value *pending_exception = get_pending_exception();
+    clear_pending_exception();
+    handle_exception(pending_exception, EX_CHECK_FULL);
+
+    set_current_state(saved_state);
+    builder()->SetInsertPoint(success);
+    push(SharkValue::create_generic(klass, object, false));
+  }
+  else {
+    push(
+      SharkValue::create_jint(
+        builder()->CreateIntCast(
+          builder()->CreateICmpEQ(
+            result, LLVMValue::jint_constant(IC_IS_INSTANCE)),
+          SharkType::jint_type(), false), false));
+  }
+}
+
+void SharkTopLevelBlock::do_trapping_instance_check(ciKlass* klass) {
+  BasicBlock *not_null = function()->CreateBlock("not_null");
+  BasicBlock *is_null  = function()->CreateBlock("null");
+
+  // Leave the object on the stack so it's there if we trap
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(xstack(0)->jobject_value(), LLVMValue::null()),
+    is_null, not_null);
+  SharkState *saved_state = current_state()->copy();
+
+  // If it's not null then we need to trap
+  builder()->SetInsertPoint(not_null);
+  set_current_state(saved_state->copy());
+  do_trap(
+    Deoptimization::make_trap_request(
+      Deoptimization::Reason_uninitialized,
+      Deoptimization::Action_reinterpret));
+
+  // If it's null then we're ok
+  builder()->SetInsertPoint(is_null);
+  set_current_state(saved_state);
+  if (bc() == Bytecodes::_checkcast) {
+    push(SharkValue::create_generic(klass, pop()->jobject_value(), false));
+  }
+  else {
+    pop();
+    push(SharkValue::jint_constant(0));
+  }
+}
+
+void SharkTopLevelBlock::do_new() {
+  bool will_link;
+  ciInstanceKlass* klass = iter()->get_klass(will_link)->as_instance_klass();
+  assert(will_link, "typeflow responsibility");
+
+  BasicBlock *got_tlab            = NULL;
+  BasicBlock *heap_alloc          = NULL;
+  BasicBlock *retry               = NULL;
+  BasicBlock *got_heap            = NULL;
+  BasicBlock *initialize          = NULL;
+  BasicBlock *got_fast            = NULL;
+  BasicBlock *slow_alloc_and_init = NULL;
+  BasicBlock *got_slow            = NULL;
+  BasicBlock *push_object         = NULL;
+
+  SharkState *fast_state = NULL;
+
+  Value *tlab_object = NULL;
+  Value *heap_object = NULL;
+  Value *fast_object = NULL;
+  Value *slow_object = NULL;
+  Value *object      = NULL;
+
+  // The fast path
+  if (!Klass::layout_helper_needs_slow_path(klass->layout_helper())) {
+    if (UseTLAB) {
+      got_tlab          = function()->CreateBlock("got_tlab");
+      heap_alloc        = function()->CreateBlock("heap_alloc");
+    }
+    retry               = function()->CreateBlock("retry");
+    got_heap            = function()->CreateBlock("got_heap");
+    initialize          = function()->CreateBlock("initialize");
+    slow_alloc_and_init = function()->CreateBlock("slow_alloc_and_init");
+    push_object         = function()->CreateBlock("push_object");
+
+    size_t size_in_bytes = klass->size_helper() << LogHeapWordSize;
+
+    // Thread local allocation
+    if (UseTLAB) {
+      Value *top_addr = builder()->CreateAddressOfStructEntry(
+        thread(), Thread::tlab_top_offset(),
+        PointerType::getUnqual(SharkType::intptr_type()),
+        "top_addr");
+
+      Value *end = builder()->CreateValueOfStructEntry(
+        thread(), Thread::tlab_end_offset(),
+        SharkType::intptr_type(),
+        "end");
+
+      Value *old_top = builder()->CreateLoad(top_addr, "old_top");
+      Value *new_top = builder()->CreateAdd(
+        old_top, LLVMValue::intptr_constant(size_in_bytes));
+
+      builder()->CreateCondBr(
+        builder()->CreateICmpULE(new_top, end),
+        got_tlab, heap_alloc);
+
+      builder()->SetInsertPoint(got_tlab);
+      tlab_object = builder()->CreateIntToPtr(
+        old_top, SharkType::oop_type(), "tlab_object");
+
+      builder()->CreateStore(new_top, top_addr);
+      builder()->CreateBr(initialize);
+
+      builder()->SetInsertPoint(heap_alloc);
+    }
+
+    // Heap allocation
+    Value *top_addr = builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) Universe::heap()->top_addr()),
+      PointerType::getUnqual(SharkType::intptr_type()),
+      "top_addr");
+
+    Value *end = builder()->CreateLoad(
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) Universe::heap()->end_addr()),
+        PointerType::getUnqual(SharkType::intptr_type())),
+      "end");
+
+    builder()->CreateBr(retry);
+    builder()->SetInsertPoint(retry);
+
+    Value *old_top = builder()->CreateLoad(top_addr, "top");
+    Value *new_top = builder()->CreateAdd(
+      old_top, LLVMValue::intptr_constant(size_in_bytes));
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpULE(new_top, end),
+      got_heap, slow_alloc_and_init);
+
+    builder()->SetInsertPoint(got_heap);
+    heap_object = builder()->CreateIntToPtr(
+      old_top, SharkType::oop_type(), "heap_object");
+
+    Value *check = builder()->CreateCmpxchgPtr(new_top, top_addr, old_top);
+    builder()->CreateCondBr(
+      builder()->CreateICmpEQ(old_top, check),
+      initialize, retry);
+
+    // Initialize the object
+    builder()->SetInsertPoint(initialize);
+    if (tlab_object) {
+      PHINode *phi = builder()->CreatePHI(
+        SharkType::oop_type(), "fast_object");
+      phi->addIncoming(tlab_object, got_tlab);
+      phi->addIncoming(heap_object, got_heap);
+      fast_object = phi;
+    }
+    else {
+      fast_object = heap_object;
+    }
+
+    builder()->CreateMemset(
+      builder()->CreateBitCast(
+        fast_object, PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jbyte_constant(0),
+      LLVMValue::jint_constant(size_in_bytes),
+      LLVMValue::jint_constant(HeapWordSize));
+
+    Value *mark_addr = builder()->CreateAddressOfStructEntry(
+      fast_object, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+      PointerType::getUnqual(SharkType::intptr_type()),
+      "mark_addr");
+
+    Value *klass_addr = builder()->CreateAddressOfStructEntry(
+      fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
+      PointerType::getUnqual(SharkType::oop_type()),
+      "klass_addr");
+
+    // Set the mark
+    intptr_t mark;
+    if (UseBiasedLocking) {
+      Unimplemented();
+    }
+    else {
+      mark = (intptr_t) markOopDesc::prototype();
+    }
+    builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr);
+
+    // Set the class
+    Value *rtklass = builder()->CreateInlineOop(klass);
+    builder()->CreateStore(rtklass, klass_addr);
+    got_fast = builder()->GetInsertBlock();
+
+    builder()->CreateBr(push_object);
+    builder()->SetInsertPoint(slow_alloc_and_init);
+    fast_state = current_state()->copy();
+  }
+
+  // The slow path
+  call_vm(
+    builder()->new_instance(),
+    LLVMValue::jint_constant(iter()->get_klass_index()),
+    EX_CHECK_FULL);
+  slow_object = get_vm_result();
+  got_slow = builder()->GetInsertBlock();
+
+  // Push the object
+  if (push_object) {
+    builder()->CreateBr(push_object);
+    builder()->SetInsertPoint(push_object);
+  }
+  if (fast_object) {
+    PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "object");
+    phi->addIncoming(fast_object, got_fast);
+    phi->addIncoming(slow_object, got_slow);
+    object = phi;
+    current_state()->merge(fast_state, got_fast, got_slow);
+  }
+  else {
+    object = slow_object;
+  }
+
+  push(SharkValue::create_jobject(object, true));
+}
+
+void SharkTopLevelBlock::do_newarray() {
+  BasicType type = (BasicType) iter()->get_index();
+
+  call_vm(
+    builder()->newarray(),
+    LLVMValue::jint_constant(type),
+    pop()->jint_value(),
+    EX_CHECK_FULL);
+
+  ciArrayKlass *array_klass = ciArrayKlass::make(ciType::make(type));
+  push(SharkValue::create_generic(array_klass, get_vm_result(), true));
+}
+
+void SharkTopLevelBlock::do_anewarray() {
+  bool will_link;
+  ciKlass *klass = iter()->get_klass(will_link);
+  assert(will_link, "typeflow responsibility");
+
+  ciObjArrayKlass *array_klass = ciObjArrayKlass::make(klass);
+  if (!array_klass->is_loaded()) {
+    Unimplemented();
+  }
+
+  call_vm(
+    builder()->anewarray(),
+    LLVMValue::jint_constant(iter()->get_klass_index()),
+    pop()->jint_value(),
+    EX_CHECK_FULL);
+
+  push(SharkValue::create_generic(array_klass, get_vm_result(), true));
+}
+
+void SharkTopLevelBlock::do_multianewarray() {
+  bool will_link;
+  ciArrayKlass *array_klass = iter()->get_klass(will_link)->as_array_klass();
+  assert(will_link, "typeflow responsibility");
+
+  // The dimensions are stack values, so we use their slots for the
+  // dimensions array.  Note that we are storing them in the reverse
+  // of normal stack order.
+  int ndims = iter()->get_dimensions();
+
+  Value *dimensions = stack()->slot_addr(
+    stack()->stack_slots_offset() + max_stack() - xstack_depth(),
+    ArrayType::get(SharkType::jint_type(), ndims),
+    "dimensions");
+
+  for (int i = 0; i < ndims; i++) {
+    builder()->CreateStore(
+      xstack(ndims - 1 - i)->jint_value(),
+      builder()->CreateStructGEP(dimensions, i));
+  }
+
+  call_vm(
+    builder()->multianewarray(),
+    LLVMValue::jint_constant(iter()->get_klass_index()),
+    LLVMValue::jint_constant(ndims),
+    builder()->CreateStructGEP(dimensions, 0),
+    EX_CHECK_FULL);
+
+  // Now we can pop the dimensions off the stack
+  for (int i = 0; i < ndims; i++)
+    pop();
+
+  push(SharkValue::create_generic(array_klass, get_vm_result(), true));
+}
+
+void SharkTopLevelBlock::acquire_method_lock() {
+  Value *lockee;
+  if (target()->is_static())
+    lockee = builder()->CreateInlineOop(target()->holder()->java_mirror());
+  else
+    lockee = local(0)->jobject_value();
+
+  iter()->force_bci(start()); // for the decache in acquire_lock
+  acquire_lock(lockee, EX_CHECK_NO_CATCH);
+}
+
+void SharkTopLevelBlock::do_monitorenter() {
+  SharkValue *lockee = pop();
+  check_null(lockee);
+  acquire_lock(lockee->jobject_value(), EX_CHECK_FULL);
+}
+
+void SharkTopLevelBlock::do_monitorexit() {
+  pop(); // don't need this (monitors are block structured)
+  release_lock(EX_CHECK_NO_CATCH);
+}
+
+void SharkTopLevelBlock::acquire_lock(Value *lockee, int exception_action) {
+  BasicBlock *try_recursive = function()->CreateBlock("try_recursive");
+  BasicBlock *got_recursive = function()->CreateBlock("got_recursive");
+  BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
+  BasicBlock *acquired_fast = function()->CreateBlock("acquired_fast");
+  BasicBlock *lock_acquired = function()->CreateBlock("lock_acquired");
+
+  int monitor = num_monitors();
+  Value *monitor_addr        = stack()->monitor_addr(monitor);
+  Value *monitor_object_addr = stack()->monitor_object_addr(monitor);
+  Value *monitor_header_addr = stack()->monitor_header_addr(monitor);
+
+  // Store the object and mark the slot as live
+  builder()->CreateStore(lockee, monitor_object_addr);
+  set_num_monitors(monitor + 1);
+
+  // Try a simple lock
+  Value *mark_addr = builder()->CreateAddressOfStructEntry(
+    lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "mark_addr");
+
+  Value *mark = builder()->CreateLoad(mark_addr, "mark");
+  Value *disp = builder()->CreateOr(
+    mark, LLVMValue::intptr_constant(markOopDesc::unlocked_value), "disp");
+  builder()->CreateStore(disp, monitor_header_addr);
+
+  Value *lock = builder()->CreatePtrToInt(
+    monitor_header_addr, SharkType::intptr_type());
+  Value *check = builder()->CreateCmpxchgPtr(lock, mark_addr, disp);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(disp, check),
+    acquired_fast, try_recursive);
+
+  // Locking failed, but maybe this thread already owns it
+  builder()->SetInsertPoint(try_recursive);
+  Value *addr = builder()->CreateAnd(
+    disp,
+    LLVMValue::intptr_constant(~markOopDesc::lock_mask_in_place));
+
+  // NB we use the entire stack, but JavaThread::is_lock_owned()
+  // uses a more limited range.  I don't think it hurts though...
+  Value *stack_limit = builder()->CreateValueOfStructEntry(
+    thread(), Thread::stack_base_offset(),
+    SharkType::intptr_type(),
+    "stack_limit");
+
+  assert(sizeof(size_t) == sizeof(intptr_t), "should be");
+  Value *stack_size = builder()->CreateValueOfStructEntry(
+    thread(), Thread::stack_size_offset(),
+    SharkType::intptr_type(),
+    "stack_size");
+
+  Value *stack_start =
+    builder()->CreateSub(stack_limit, stack_size, "stack_start");
+
+  builder()->CreateCondBr(
+    builder()->CreateAnd(
+      builder()->CreateICmpUGE(addr, stack_start),
+      builder()->CreateICmpULT(addr, stack_limit)),
+    got_recursive, not_recursive);
+
+  builder()->SetInsertPoint(got_recursive);
+  builder()->CreateStore(LLVMValue::intptr_constant(0), monitor_header_addr);
+  builder()->CreateBr(acquired_fast);
+
+  // Create an edge for the state merge
+  builder()->SetInsertPoint(acquired_fast);
+  SharkState *fast_state = current_state()->copy();
+  builder()->CreateBr(lock_acquired);
+
+  // It's not a recursive case so we need to drop into the runtime
+  builder()->SetInsertPoint(not_recursive);
+  call_vm(
+    builder()->monitorenter(), monitor_addr,
+    exception_action | EAM_MONITOR_FUDGE);
+  BasicBlock *acquired_slow = builder()->GetInsertBlock();
+  builder()->CreateBr(lock_acquired);
+
+  // All done
+  builder()->SetInsertPoint(lock_acquired);
+  current_state()->merge(fast_state, acquired_fast, acquired_slow);
+}
+
+void SharkTopLevelBlock::release_lock(int exception_action) {
+  BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
+  BasicBlock *released_fast = function()->CreateBlock("released_fast");
+  BasicBlock *slow_path     = function()->CreateBlock("slow_path");
+  BasicBlock *lock_released = function()->CreateBlock("lock_released");
+
+  int monitor = num_monitors() - 1;
+  Value *monitor_addr        = stack()->monitor_addr(monitor);
+  Value *monitor_object_addr = stack()->monitor_object_addr(monitor);
+  Value *monitor_header_addr = stack()->monitor_header_addr(monitor);
+
+  // If it is recursive then we're already done
+  Value *disp = builder()->CreateLoad(monitor_header_addr);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(disp, LLVMValue::intptr_constant(0)),
+    released_fast, not_recursive);
+
+  // Try a simple unlock
+  builder()->SetInsertPoint(not_recursive);
+
+  Value *lock = builder()->CreatePtrToInt(
+    monitor_header_addr, SharkType::intptr_type());
+
+  Value *lockee = builder()->CreateLoad(monitor_object_addr);
+
+  Value *mark_addr = builder()->CreateAddressOfStructEntry(
+    lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "mark_addr");
+
+  Value *check = builder()->CreateCmpxchgPtr(disp, mark_addr, lock);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(lock, check),
+    released_fast, slow_path);
+
+  // Create an edge for the state merge
+  builder()->SetInsertPoint(released_fast);
+  SharkState *fast_state = current_state()->copy();
+  builder()->CreateBr(lock_released);
+
+  // Need to drop into the runtime to release this one
+  builder()->SetInsertPoint(slow_path);
+  call_vm(builder()->monitorexit(), monitor_addr, exception_action);
+  BasicBlock *released_slow = builder()->GetInsertBlock();
+  builder()->CreateBr(lock_released);
+
+  // All done
+  builder()->SetInsertPoint(lock_released);
+  current_state()->merge(fast_state, released_fast, released_slow);
+
+  // The object slot is now dead
+  set_num_monitors(monitor);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkTopLevelBlock : public SharkBlock {
+ public:
+  SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock)
+    : SharkBlock(function),
+      _function(function),
+      _ciblock(ciblock),
+      _entered(false),
+      _has_trap(false),
+      _needs_phis(false),
+      _entry_state(NULL),
+      _entry_block(NULL) {}
+
+ private:
+  SharkFunction*     _function;
+  ciTypeFlow::Block* _ciblock;
+
+ public:
+  SharkFunction* function() const {
+    return _function;
+  }
+  ciTypeFlow::Block* ciblock() const {
+    return _ciblock;
+  }
+
+  // Function properties
+ public:
+  SharkStack* stack() const {
+    return function()->stack();
+  }
+
+  // Typeflow properties
+ public:
+  int index() const {
+    return ciblock()->pre_order();
+  }
+  bool is_backedge_copy() const {
+    return ciblock()->is_backedge_copy();
+  }
+  int stack_depth_at_entry() const {
+    return ciblock()->stack_size();
+  }
+  ciType* local_type_at_entry(int index) const {
+    return ciblock()->local_type_at(index);
+  }
+  ciType* stack_type_at_entry(int slot) const {
+    return ciblock()->stack_type_at(slot);
+  }
+  int start() const {
+    return ciblock()->start();
+  }
+  int limit() const {
+    return ciblock()->limit();
+  }
+  bool falls_through() const {
+    return ciblock()->control() == ciBlock::fall_through_bci;
+  }
+  int num_successors() const {
+    return ciblock()->successors()->length();
+  }
+  SharkTopLevelBlock* successor(int index) const {
+    return function()->block(ciblock()->successors()->at(index)->pre_order());
+  }
+  SharkTopLevelBlock* bci_successor(int bci) const;
+
+  // Exceptions
+ private:
+  GrowableArray<ciExceptionHandler*>* _exc_handlers;
+  GrowableArray<SharkTopLevelBlock*>* _exceptions;
+
+ private:
+  void compute_exceptions();
+
+ private:
+  int num_exceptions() const {
+    return _exc_handlers->length();
+  }
+  ciExceptionHandler* exc_handler(int index) const {
+    return _exc_handlers->at(index);
+  }
+  SharkTopLevelBlock* exception(int index) const {
+    return _exceptions->at(index);
+  }
+
+  // Traps
+ private:
+  bool _has_trap;
+  int  _trap_request;
+  int  _trap_bci;
+
+  void set_trap(int trap_request, int trap_bci) {
+    assert(!has_trap(), "shouldn't have");
+    _has_trap     = true;
+    _trap_request = trap_request;
+    _trap_bci     = trap_bci;
+  }
+
+ private:
+  bool has_trap() {
+    return _has_trap;
+  }
+  int trap_request() {
+    assert(has_trap(), "should have");
+    return _trap_request;
+  }
+  int trap_bci() {
+    assert(has_trap(), "should have");
+    return _trap_bci;
+  }
+
+ private:
+  void scan_for_traps();
+
+ private:
+  bool static_field_ok_in_clinit(ciField* field);
+
+  // Entry state
+ private:
+  bool _entered;
+  bool _needs_phis;
+
+ public:
+  bool entered() const {
+    return _entered;
+  }
+  bool needs_phis() const {
+    return _needs_phis;
+  }
+
+ private:
+  void enter(SharkTopLevelBlock* predecessor, bool is_exception);
+
+ public:
+  void enter() {
+    enter(NULL, false);
+  }
+
+ private:
+  SharkState* _entry_state;
+
+ private:
+  SharkState* entry_state();
+
+ private:
+  llvm::BasicBlock* _entry_block;
+
+ public:
+  llvm::BasicBlock* entry_block() const {
+    return _entry_block;
+  }
+
+ public:
+  void initialize();
+
+ public:
+  void add_incoming(SharkState* incoming_state);
+
+  // Method
+ public:
+  llvm::Value* method() {
+    return current_state()->method();
+  }
+
+  // Temporary oop storage
+ public:
+  void set_oop_tmp(llvm::Value* value) {
+    assert(value, "value must be non-NULL (will be reset by get_oop_tmp)");
+    assert(!current_state()->oop_tmp(), "oop_tmp gets and sets must match");
+    current_state()->set_oop_tmp(value);
+  }
+  llvm::Value* get_oop_tmp() {
+    llvm::Value* value = current_state()->oop_tmp();
+    assert(value, "oop_tmp gets and sets must match");
+    current_state()->set_oop_tmp(NULL);
+    return value;
+  }
+
+  // Cache and decache
+ private:
+  void decache_for_Java_call(ciMethod* callee);
+  void cache_after_Java_call(ciMethod* callee);
+  void decache_for_VM_call();
+  void cache_after_VM_call();
+  void decache_for_trap();
+
+  // Monitors
+ private:
+  int num_monitors() {
+    return current_state()->num_monitors();
+  }
+  int set_num_monitors(int num_monitors) {
+    current_state()->set_num_monitors(num_monitors);
+  }
+
+  // Code generation
+ public:
+  void emit_IR();
+
+  // Branch helpers
+ private:
+  void do_branch(int successor_index);
+
+  // Zero checks
+ private:
+  void do_zero_check(SharkValue* value);
+  void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);
+
+ public:
+  void do_deferred_zero_check(SharkValue*       value,
+                              int               bci,
+                              SharkState*       saved_state,
+                              llvm::BasicBlock* continue_block);
+  // Exceptions
+ private:
+  llvm::Value* pending_exception_address() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(), Thread::pending_exception_offset(),
+      llvm::PointerType::getUnqual(SharkType::oop_type()),
+      "pending_exception_addr");
+  }
+  llvm::LoadInst* get_pending_exception() const {
+    return builder()->CreateLoad(
+      pending_exception_address(), "pending_exception");
+  }
+  void clear_pending_exception() const {
+    builder()->CreateStore(LLVMValue::null(), pending_exception_address());
+  }
+ public:
+  enum ExceptionActionMask {
+    // The actual bitmasks that things test against
+    EAM_CHECK         = 1, // whether to check for pending exceptions
+    EAM_HANDLE        = 2, // whether to attempt to handle pending exceptions
+    EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting
+
+    // More convenient values for passing
+    EX_CHECK_NONE     = 0,
+    EX_CHECK_NO_CATCH = EAM_CHECK,
+    EX_CHECK_FULL     = EAM_CHECK | EAM_HANDLE
+  };
+  void check_pending_exception(int action);
+  void handle_exception(llvm::Value* exception, int action);
+  void marshal_exception_fast(int num_options);
+  void marshal_exception_slow(int num_options);
+  llvm::BasicBlock* handler_for_exception(int index);
+
+  // VM calls
+ private:
+  llvm::CallInst* call_vm(llvm::Value*  callee,
+                          llvm::Value** args_start,
+                          llvm::Value** args_end,
+                          int           exception_action) {
+    decache_for_VM_call();
+    stack()->CreateSetLastJavaFrame();
+    llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end);
+    stack()->CreateResetLastJavaFrame();
+    cache_after_VM_call();
+    if (exception_action & EAM_CHECK) {
+      check_pending_exception(exception_action);
+      current_state()->set_has_safepointed(true);
+    }
+    return res;
+  }
+
+ public:
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread()};
+    return call_vm(callee, args, args + 1, exception_action);
+  }
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          llvm::Value* arg1,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread(), arg1};
+    return call_vm(callee, args, args + 2, exception_action);
+  }
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          llvm::Value* arg1,
+                          llvm::Value* arg2,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread(), arg1, arg2};
+    return call_vm(callee, args, args + 3, exception_action);
+  }
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          llvm::Value* arg1,
+                          llvm::Value* arg2,
+                          llvm::Value* arg3,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread(), arg1, arg2, arg3};
+    return call_vm(callee, args, args + 4, exception_action);
+  }
+
+  // VM call oop return handling
+ private:
+  llvm::LoadInst* get_vm_result() const {
+    llvm::Value *addr = builder()->CreateAddressOfStructEntry(
+      thread(), JavaThread::vm_result_offset(),
+      llvm::PointerType::getUnqual(SharkType::oop_type()),
+      "vm_result_addr");
+    llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");
+    builder()->CreateStore(LLVMValue::null(), addr);
+    return result;
+  }
+
+  // Synchronization
+ private:
+  void acquire_lock(llvm::Value* lockee, int exception_action);
+  void release_lock(int exception_action);
+
+ public:
+  void acquire_method_lock();
+
+  // Bounds checks
+ private:
+  void check_bounds(SharkValue* array, SharkValue* index);
+
+  // Safepoints
+ private:
+  void maybe_add_safepoint();
+  void maybe_add_backedge_safepoint();
+
+  // Loop safepoint removal
+ private:
+  bool _can_reach_visited;
+
+  bool can_reach(SharkTopLevelBlock* other);
+  bool can_reach_helper(SharkTopLevelBlock* other);
+
+  // Traps
+ private:
+  llvm::BasicBlock* make_trap(int trap_bci, int trap_request);
+  void do_trap(int trap_request);
+
+  // Returns
+ private:
+  void call_register_finalizer(llvm::Value* receiver);
+  void handle_return(BasicType type, llvm::Value* exception);
+
+  // arraylength
+ private:
+  void do_arraylength();
+
+  // *aload and *astore
+ private:
+  void do_aload(BasicType basic_type);
+  void do_astore(BasicType basic_type);
+
+  // *return and athrow
+ private:
+  void do_return(BasicType type);
+  void do_athrow();
+
+  // goto*
+ private:
+  void do_goto();
+
+  // jsr* and ret
+ private:
+  void do_jsr();
+  void do_ret();
+
+  // if*
+ private:
+  void do_if_helper(llvm::ICmpInst::Predicate p,
+                    llvm::Value*              b,
+                    llvm::Value*              a,
+                    SharkState*               if_taken_state,
+                    SharkState*               not_taken_state);
+  void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
+
+  // tableswitch and lookupswitch
+ private:
+  void do_switch();
+
+  // invoke*
+ private:
+  ciMethod* improve_virtual_call(ciMethod*        caller,
+                                 ciInstanceKlass* klass,
+                                 ciMethod*        dest_method,
+                                 ciType*          receiver_type);
+  llvm::Value* get_direct_callee(ciMethod* method);
+  llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index);
+  llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method);
+
+  void do_call();
+
+  // checkcast and instanceof
+ private:
+  bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass);
+  void do_full_instance_check(ciKlass* klass);
+  void do_trapping_instance_check(ciKlass* klass);
+
+  void do_instance_check();
+  bool maybe_do_instanceof_if();
+
+  // new and *newarray
+ private:
+  void do_new();
+  void do_newarray();
+  void do_anewarray();
+  void do_multianewarray();
+
+  // monitorenter and monitorexit
+ private:
+  void do_monitorenter();
+  void do_monitorexit();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkType.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+class SharkType : public AllStatic {
+ private:
+  static SharkContext& context() {
+    return SharkContext::current();
+  }
+
+  // Basic types
+ public:
+  static const llvm::Type* void_type() {
+    return context().void_type();
+  }
+  static const llvm::IntegerType* bit_type() {
+    return context().bit_type();
+  }
+  static const llvm::IntegerType* jbyte_type() {
+    return context().jbyte_type();
+  }
+  static const llvm::IntegerType* jshort_type() {
+    return context().jshort_type();
+  }
+  static const llvm::IntegerType* jint_type() {
+    return context().jint_type();
+  }
+  static const llvm::IntegerType* jlong_type() {
+    return context().jlong_type();
+  }
+  static const llvm::Type* jfloat_type() {
+    return context().jfloat_type();
+  }
+  static const llvm::Type* jdouble_type() {
+    return context().jdouble_type();
+  }
+  static const llvm::IntegerType* intptr_type() {
+    return context().intptr_type();
+  }
+
+  // Compound types
+ public:
+  static const llvm::PointerType* itableOffsetEntry_type() {
+    return context().itableOffsetEntry_type();
+  }
+  static const llvm::PointerType* jniEnv_type() {
+    return context().jniEnv_type();
+  }
+  static const llvm::PointerType* jniHandleBlock_type() {
+    return context().jniHandleBlock_type();
+  }
+  static const llvm::PointerType* klass_type() {
+    return context().klass_type();
+  }
+  static const llvm::PointerType* methodOop_type() {
+    return context().methodOop_type();
+  }
+  static const llvm::ArrayType* monitor_type() {
+    return context().monitor_type();
+  }
+  static const llvm::PointerType* oop_type() {
+    return context().oop_type();
+  }
+  static const llvm::PointerType* thread_type() {
+    return context().thread_type();
+  }
+  static const llvm::PointerType* zeroStack_type() {
+    return context().zeroStack_type();
+  }
+  static const llvm::FunctionType* entry_point_type() {
+    return context().entry_point_type();
+  }
+  static const llvm::FunctionType* osr_entry_point_type() {
+    return context().osr_entry_point_type();
+  }
+
+  // Mappings
+ public:
+  static const llvm::Type* to_stackType(BasicType type) {
+    return context().to_stackType(type);
+  }
+  static const llvm::Type* to_stackType(ciType* type) {
+    return to_stackType(type->basic_type());
+  }
+  static const llvm::Type* to_arrayType(BasicType type) {
+    return context().to_arrayType(type);
+  }
+  static const llvm::Type* to_arrayType(ciType* type) {
+    return to_arrayType(type->basic_type());
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkValue.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkValue.cpp.incl"
+
+using namespace llvm;
+
+// Cloning
+
+SharkValue* SharkNormalValue::clone() const {
+  return SharkValue::create_generic(type(), generic_value(), zero_checked());
+}
+SharkValue* SharkPHIValue::clone() const {
+  return SharkValue::create_phi(type(), (PHINode *) generic_value(), this);
+}
+SharkValue* SharkAddressValue::clone() const {
+  return SharkValue::address_constant(address_value());
+}
+
+// Casting
+
+bool SharkValue::is_phi() const {
+  return false;
+}
+bool SharkPHIValue::is_phi() const {
+  return true;
+}
+SharkPHIValue* SharkValue::as_phi() {
+  ShouldNotCallThis();
+}
+SharkPHIValue* SharkPHIValue::as_phi() {
+  return this;
+}
+
+// Comparison
+
+bool SharkNormalValue::equal_to(SharkValue *other) const {
+  return (this->type()          == other->type() &&
+          this->generic_value() == other->generic_value() &&
+          this->zero_checked()  == other->zero_checked());
+}
+bool SharkAddressValue::equal_to(SharkValue *other) const {
+  return (this->address_value() == other->address_value());
+}
+
+// Type access
+
+ciType* SharkValue::type() const {
+  ShouldNotCallThis();
+}
+ciType* SharkNormalValue::type() const {
+  return _type;
+}
+
+BasicType SharkNormalValue::basic_type() const {
+  return type()->basic_type();
+}
+BasicType SharkAddressValue::basic_type() const {
+  return T_ADDRESS;
+}
+
+int SharkNormalValue::size() const {
+  return type()->size();
+}
+int SharkAddressValue::size() const {
+  return 1;
+}
+
+bool SharkValue::is_jint() const {
+  return false;
+}
+bool SharkValue::is_jlong() const {
+  return false;
+}
+bool SharkValue::is_jfloat() const {
+  return false;
+}
+bool SharkValue::is_jdouble() const {
+  return false;
+}
+bool SharkValue::is_jobject() const {
+  return false;
+}
+bool SharkValue::is_jarray() const {
+  return false;
+}
+bool SharkValue::is_address() const {
+  return false;
+}
+
+bool SharkNormalValue::is_jint() const {
+  return llvm_value()->getType() == SharkType::jint_type();
+}
+bool SharkNormalValue::is_jlong() const {
+  return llvm_value()->getType() == SharkType::jlong_type();
+}
+bool SharkNormalValue::is_jfloat() const {
+  return llvm_value()->getType() == SharkType::jfloat_type();
+}
+bool SharkNormalValue::is_jdouble() const {
+  return llvm_value()->getType() == SharkType::jdouble_type();
+}
+bool SharkNormalValue::is_jobject() const {
+  return llvm_value()->getType() == SharkType::oop_type();
+}
+bool SharkNormalValue::is_jarray() const {
+  return basic_type() == T_ARRAY;
+}
+bool SharkAddressValue::is_address() const {
+  return true;
+}
+
+// Typed conversions from SharkValues
+
+Value* SharkValue::jint_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jlong_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jfloat_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jdouble_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jobject_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jarray_value() const {
+  ShouldNotCallThis();
+}
+int SharkValue::address_value() const {
+  ShouldNotCallThis();
+}
+
+Value* SharkNormalValue::jint_value() const {
+  assert(is_jint(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jlong_value() const {
+  assert(is_jlong(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jfloat_value() const {
+  assert(is_jfloat(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jdouble_value() const {
+  assert(is_jdouble(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jobject_value() const {
+  assert(is_jobject(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jarray_value() const {
+  // XXX assert(is_jarray(), "should be");
+  // XXX http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=324
+  assert(is_jobject(), "should be");
+  return llvm_value();
+}
+int SharkAddressValue::address_value() const {
+  return _bci;
+}
+
+// Type-losing conversions -- use with care!
+
+Value* SharkNormalValue::generic_value() const {
+  return llvm_value();
+}
+Value* SharkAddressValue::generic_value() const {
+  return LLVMValue::intptr_constant(address_value());
+}
+
+Value* SharkValue::intptr_value(SharkBuilder* builder) const {
+  ShouldNotCallThis();
+}
+Value* SharkNormalValue::intptr_value(SharkBuilder* builder) const {
+  return builder->CreatePtrToInt(jobject_value(), SharkType::intptr_type());
+}
+
+// Phi-style stuff for SharkPHIState::add_incoming
+
+void SharkValue::addIncoming(SharkValue *value, BasicBlock* block) {
+  ShouldNotCallThis();
+}
+void SharkPHIValue::addIncoming(SharkValue *value, BasicBlock* block) {
+  assert(!is_clone(), "shouldn't be");
+  ((llvm::PHINode *) generic_value())->addIncoming(
+      value->generic_value(), block);
+  if (!value->zero_checked())
+    _all_incomers_zero_checked = false;
+}
+void SharkAddressValue::addIncoming(SharkValue *value, BasicBlock* block) {
+  assert(this->equal_to(value), "should be");
+}
+
+// Phi-style stuff for SharkState::merge
+
+SharkValue* SharkNormalValue::merge(SharkBuilder* builder,
+                                    SharkValue*   other,
+                                    BasicBlock*   other_block,
+                                    BasicBlock*   this_block,
+                                    const char*   name) {
+  assert(type() == other->type(), "should be");
+  assert(zero_checked() == other->zero_checked(), "should be");
+
+  PHINode *phi = builder->CreatePHI(SharkType::to_stackType(type()), name);
+  phi->addIncoming(this->generic_value(), this_block);
+  phi->addIncoming(other->generic_value(), other_block);
+  return SharkValue::create_generic(type(), phi, zero_checked());
+}
+SharkValue* SharkAddressValue::merge(SharkBuilder* builder,
+                                     SharkValue*   other,
+                                     BasicBlock*   other_block,
+                                     BasicBlock*   this_block,
+                                     const char*   name) {
+  assert(this->equal_to(other), "should be");
+  return this;
+}
+
+// Repeated null and divide-by-zero check removal
+
+bool SharkValue::zero_checked() const {
+  ShouldNotCallThis();
+}
+void SharkValue::set_zero_checked(bool zero_checked) {
+  ShouldNotCallThis();
+}
+
+bool SharkNormalValue::zero_checked() const {
+  return _zero_checked;
+}
+void SharkNormalValue::set_zero_checked(bool zero_checked) {
+  _zero_checked = zero_checked;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkValue.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// Items on the stack and in local variables are tracked using
+// SharkValue objects.
+//
+// All SharkValues are one of two core types, SharkNormalValue
+// and SharkAddressValue, but no code outside this file should
+// ever refer to those directly.  The split is because of the
+// way JSRs are handled: the typeflow pass expands them into
+// multiple copies, so the return addresses pushed by jsr and
+// popped by ret only exist at compile time.  Having separate
+// classes for these allows us to check that our jsr handling
+// is correct, via assertions.
+//
+// There is one more type, SharkPHIValue, which is a subclass
+// of SharkNormalValue with a couple of extra methods.  Use of
+// SharkPHIValue outside of this file is acceptable, so long
+// as it is obtained via SharkValue::as_phi().
+
+class SharkBuilder;
+class SharkPHIValue;
+
+class SharkValue : public ResourceObj {
+ protected:
+  SharkValue() {}
+
+  // Cloning
+ public:
+  virtual SharkValue* clone() const = 0;
+
+  // Casting
+ public:
+  virtual bool           is_phi() const;
+  virtual SharkPHIValue* as_phi();
+
+  // Comparison
+ public:
+  virtual bool equal_to(SharkValue* other) const = 0;
+
+  // Type access
+ public:
+  virtual BasicType basic_type() const = 0;
+  virtual ciType*   type()       const;
+
+  virtual bool is_jint()    const;
+  virtual bool is_jlong()   const;
+  virtual bool is_jfloat()  const;
+  virtual bool is_jdouble() const;
+  virtual bool is_jobject() const;
+  virtual bool is_jarray()  const;
+  virtual bool is_address() const;
+
+  virtual int size() const = 0;
+
+  bool is_one_word() const {
+    return size() == 1;
+  }
+  bool is_two_word() const {
+    return size() == 2;
+  }
+
+  // Typed conversion from SharkValues
+ public:
+  virtual llvm::Value* jint_value()    const;
+  virtual llvm::Value* jlong_value()   const;
+  virtual llvm::Value* jfloat_value()  const;
+  virtual llvm::Value* jdouble_value() const;
+  virtual llvm::Value* jobject_value() const;
+  virtual llvm::Value* jarray_value()  const;
+  virtual int          address_value() const;
+
+  // Typed conversion to SharkValues
+ public:
+  static SharkValue* create_jint(llvm::Value* value, bool zero_checked) {
+    assert(value->getType() == SharkType::jint_type(), "should be");
+    return create_generic(ciType::make(T_INT), value, zero_checked);
+  }
+  static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) {
+    assert(value->getType() == SharkType::jlong_type(), "should be");
+    return create_generic(ciType::make(T_LONG), value, zero_checked);
+  }
+  static SharkValue* create_jfloat(llvm::Value* value) {
+    assert(value->getType() == SharkType::jfloat_type(), "should be");
+    return create_generic(ciType::make(T_FLOAT), value, false);
+  }
+  static SharkValue* create_jdouble(llvm::Value* value) {
+    assert(value->getType() == SharkType::jdouble_type(), "should be");
+    return create_generic(ciType::make(T_DOUBLE), value, false);
+  }
+  static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) {
+    assert(value->getType() == SharkType::oop_type(), "should be");
+    return create_generic(ciType::make(T_OBJECT), value, zero_checked);
+  }
+
+  // Typed conversion from constants of various types
+ public:
+  static SharkValue* jint_constant(jint value) {
+    return create_jint(LLVMValue::jint_constant(value), value != 0);
+  }
+  static SharkValue* jlong_constant(jlong value) {
+    return create_jlong(LLVMValue::jlong_constant(value), value != 0);
+  }
+  static SharkValue* jfloat_constant(jfloat value) {
+    return create_jfloat(LLVMValue::jfloat_constant(value));
+  }
+  static SharkValue* jdouble_constant(jdouble value) {
+    return create_jdouble(LLVMValue::jdouble_constant(value));
+  }
+  static SharkValue* null() {
+    return create_jobject(LLVMValue::null(), false);
+  }
+  static inline SharkValue* address_constant(int bci);
+
+  // Type-losing conversions -- use with care!
+ public:
+  virtual llvm::Value* generic_value() const = 0;
+  virtual llvm::Value* intptr_value(SharkBuilder* builder) const;
+
+  static inline SharkValue* create_generic(ciType*      type,
+                                           llvm::Value* value,
+                                           bool         zero_checked);
+  static inline SharkValue* create_phi(ciType*              type,
+                                       llvm::PHINode*       phi,
+                                       const SharkPHIValue* parent = NULL);
+
+  // Phi-style stuff
+ public:
+  virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block);
+  virtual SharkValue* merge(SharkBuilder*     builder,
+                            SharkValue*       other,
+                            llvm::BasicBlock* other_block,
+                            llvm::BasicBlock* this_block,
+                            const char*       name) = 0;
+
+  // Repeated null and divide-by-zero check removal
+ public:
+  virtual bool zero_checked() const;
+  virtual void set_zero_checked(bool zero_checked);
+};
+
+class SharkNormalValue : public SharkValue {
+  friend class SharkValue;
+
+ protected:
+  SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked)
+    : _type(type), _llvm_value(value), _zero_checked(zero_checked) {}
+
+ private:
+  ciType*      _type;
+  llvm::Value* _llvm_value;
+  bool         _zero_checked;
+
+ private:
+  llvm::Value* llvm_value() const {
+    return _llvm_value;
+  }
+
+  // Cloning
+ public:
+  SharkValue* clone() const;
+
+  // Comparison
+ public:
+  bool equal_to(SharkValue* other) const;
+
+  // Type access
+ public:
+  ciType*   type()       const;
+  BasicType basic_type() const;
+  int       size()       const;
+
+ public:
+  bool is_jint()    const;
+  bool is_jlong()   const;
+  bool is_jfloat()  const;
+  bool is_jdouble() const;
+  bool is_jobject() const;
+  bool is_jarray()  const;
+
+  // Typed conversions to LLVM values
+ public:
+  llvm::Value* jint_value()    const;
+  llvm::Value* jlong_value()   const;
+  llvm::Value* jfloat_value()  const;
+  llvm::Value* jdouble_value() const;
+  llvm::Value* jobject_value() const;
+  llvm::Value* jarray_value()  const;
+
+  // Type-losing conversions, use with care
+ public:
+  llvm::Value* generic_value() const;
+  llvm::Value* intptr_value(SharkBuilder* builder) const;
+
+  // Phi-style stuff
+ public:
+  SharkValue* merge(SharkBuilder*     builder,
+                    SharkValue*       other,
+                    llvm::BasicBlock* other_block,
+                    llvm::BasicBlock* this_block,
+                    const char*       name);
+
+  // Repeated null and divide-by-zero check removal
+ public:
+  bool zero_checked() const;
+  void set_zero_checked(bool zero_checked);
+};
+
+class SharkPHIValue : public SharkNormalValue {
+  friend class SharkValue;
+
+ protected:
+  SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent)
+    : SharkNormalValue(type, phi, parent && parent->zero_checked()),
+      _parent(parent),
+      _all_incomers_zero_checked(true) {}
+
+ private:
+  const SharkPHIValue* _parent;
+  bool                 _all_incomers_zero_checked;
+
+ private:
+  const SharkPHIValue* parent() const {
+    return _parent;
+  }
+  bool is_clone() const {
+    return parent() != NULL;
+  }
+
+ public:
+  bool all_incomers_zero_checked() const {
+    if (is_clone())
+      return parent()->all_incomers_zero_checked();
+
+    return _all_incomers_zero_checked;
+  }
+
+  // Cloning
+ public:
+  SharkValue* clone() const;
+
+  // Casting
+ public:
+  bool           is_phi() const;
+  SharkPHIValue* as_phi();
+
+  // Phi-style stuff
+ public:
+  void addIncoming(SharkValue *value, llvm::BasicBlock* block);
+};
+
+class SharkAddressValue : public SharkValue {
+  friend class SharkValue;
+
+ protected:
+  SharkAddressValue(int bci)
+    : _bci(bci) {}
+
+ private:
+  int _bci;
+
+  // Cloning
+ public:
+  SharkValue* clone() const;
+
+  // Comparison
+ public:
+  bool equal_to(SharkValue* other) const;
+
+  // Type access
+ public:
+  BasicType basic_type() const;
+  int       size()       const;
+  bool      is_address() const;
+
+  // Typed conversion from SharkValues
+ public:
+  int address_value() const;
+
+  // Type-losing conversion -- use with care!
+ public:
+  llvm::Value* generic_value() const;
+
+  // Phi-style stuff
+ public:
+  void addIncoming(SharkValue *value, llvm::BasicBlock* block);
+  SharkValue* merge(SharkBuilder*     builder,
+                    SharkValue*       other,
+                    llvm::BasicBlock* other_block,
+                    llvm::BasicBlock* this_block,
+                    const char*       name);
+};
+
+// SharkValue methods that can't be declared above
+
+inline SharkValue* SharkValue::create_generic(ciType*      type,
+                                              llvm::Value* value,
+                                              bool         zero_checked) {
+  return new SharkNormalValue(type, value, zero_checked);
+}
+
+inline SharkValue* SharkValue::create_phi(ciType*              type,
+                                          llvm::PHINode*       phi,
+                                          const SharkPHIValue* parent) {
+  return new SharkPHIValue(type, phi, parent);
+}
+
+inline SharkValue* SharkValue::address_constant(int bci) {
+  return new SharkAddressValue(bci);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/shark_globals.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_shark_globals.cpp.incl"
+
+SHARK_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/shark_globals.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ *
+ */
+
+#define SHARK_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
+                                                                              \
+  product(intx, MaxNodeLimit, 65000,                                          \
+          "Maximum number of nodes")                                          \
+                                                                              \
+  /* inlining */                                                              \
+  product(intx, SharkMaxInlineSize, 32,                                       \
+          "Maximum bytecode size of methods to inline when using Shark")      \
+                                                                              \
+  /* compiler debugging */                                                    \
+  develop(ccstr, SharkPrintTypeflowOf, NULL,                                  \
+          "Print the typeflow of the specified method")                       \
+                                                                              \
+  diagnostic(ccstr, SharkPrintBitcodeOf, NULL,                                \
+          "Print the LLVM bitcode of the specified method")                   \
+                                                                              \
+  diagnostic(ccstr, SharkPrintAsmOf, NULL,                                    \
+          "Print the asm of the specified method")                            \
+                                                                              \
+  develop(bool, SharkTraceBytecodes, false,                                   \
+          "Trace bytecode compilation")                                       \
+                                                                              \
+  diagnostic(bool, SharkTraceInstalls, false,                                 \
+          "Trace method installation")                                        \
+                                                                              \
+  diagnostic(bool, SharkPerformanceWarnings, false,                           \
+          "Warn about things that could be made faster")                      \
+
+SHARK_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/utilities/debug.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -552,140 +552,6 @@
   }
 }
 
-
-static void find(intptr_t x, bool print_pc) {
-  address addr = (address)x;
-
-  CodeBlob* b = CodeCache::find_blob_unsafe(addr);
-  if (b != NULL) {
-    if (b->is_buffer_blob()) {
-      // the interpreter is generated into a buffer blob
-      InterpreterCodelet* i = Interpreter::codelet_containing(addr);
-      if (i != NULL) {
-        i->print();
-        return;
-      }
-      if (Interpreter::contains(addr)) {
-        tty->print_cr(INTPTR_FORMAT " is pointing into interpreter code (not bytecode specific)", addr);
-        return;
-      }
-      //
-      if (AdapterHandlerLibrary::contains(b)) {
-        AdapterHandlerLibrary::print_handler(b);
-      }
-      // the stubroutines are generated into a buffer blob
-      StubCodeDesc* d = StubCodeDesc::desc_for(addr);
-      if (d != NULL) {
-        d->print();
-        if (print_pc) tty->cr();
-        return;
-      }
-      if (StubRoutines::contains(addr)) {
-        tty->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", addr);
-        return;
-      }
-      // the InlineCacheBuffer is using stubs generated into a buffer blob
-      if (InlineCacheBuffer::contains(addr)) {
-        tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
-        return;
-      }
-      VtableStub* v = VtableStubs::stub_containing(addr);
-      if (v != NULL) {
-        v->print();
-        return;
-      }
-    }
-    if (print_pc && b->is_nmethod()) {
-      ResourceMark rm;
-      tty->print("%#p: Compiled ", addr);
-      ((nmethod*)b)->method()->print_value_on(tty);
-      tty->print("  = (CodeBlob*)" INTPTR_FORMAT, b);
-      tty->cr();
-      return;
-    }
-    if ( b->is_nmethod()) {
-      if (b->is_zombie()) {
-        tty->print_cr(INTPTR_FORMAT " is zombie nmethod", b);
-      } else if (b->is_not_entrant()) {
-        tty->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b);
-      }
-    }
-    b->print();
-    return;
-  }
-
-  if (Universe::heap()->is_in(addr)) {
-    HeapWord* p = Universe::heap()->block_start(addr);
-    bool print = false;
-    // If we couldn't find it it just may mean that heap wasn't parseable
-    // See if we were just given an oop directly
-    if (p != NULL && Universe::heap()->block_is_obj(p)) {
-      print = true;
-    } else if (p == NULL && ((oopDesc*)addr)->is_oop()) {
-      p = (HeapWord*) addr;
-      print = true;
-    }
-    if (print) {
-      oop(p)->print();
-      if (p != (HeapWord*)x && oop(p)->is_constMethod() &&
-          constMethodOop(p)->contains(addr)) {
-        Thread *thread = Thread::current();
-        HandleMark hm(thread);
-        methodHandle mh (thread, constMethodOop(p)->method());
-        if (!mh->is_native()) {
-          tty->print_cr("bci_from(%p) = %d; print_codes():",
-                        addr, mh->bci_from(address(x)));
-          mh->print_codes();
-        }
-      }
-      return;
-    }
-  } else if (Universe::heap()->is_in_reserved(addr)) {
-    tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr);
-    return;
-  }
-
-  if (JNIHandles::is_global_handle((jobject) addr)) {
-    tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
-    return;
-  }
-  if (JNIHandles::is_weak_global_handle((jobject) addr)) {
-    tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
-    return;
-  }
-  if (JNIHandleBlock::any_contains((jobject) addr)) {
-    tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
-    return;
-  }
-
-  for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
-    // Check for privilege stack
-    if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
-      tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread);
-      return;
-    }
-    // If the addr is a java thread print information about that.
-    if (addr == (address)thread) {
-       thread->print();
-       return;
-    }
-  }
-
-  // Try an OS specific find
-  if (os::find(addr)) {
-    return;
-  }
-
-  if (print_pc) {
-    tty->print_cr(INTPTR_FORMAT ": probably in C++ code; check debugger", addr);
-    Disassembler::decode(same_page(addr-40,addr),same_page(addr+40,addr));
-    return;
-  }
-
-  tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
-}
-
-
 class LookForRefInGenClosure : public OopsInGenClosure {
 public:
   oop target;
@@ -767,7 +633,7 @@
 // Can we someday rename the other find to hsfind?
 extern "C" void hsfind(intptr_t x) {
   Command c("hsfind");
-  find(x, false);
+  os::print_location(tty, x, false);
 }
 
 
@@ -778,13 +644,13 @@
 
 extern "C" void find(intptr_t x) {
   Command c("find");
-  find(x, false);
+  os::print_location(tty, x, false);
 }
 
 
 extern "C" void findpc(intptr_t x) {
   Command c("findpc");
-  find(x, true);
+  os::print_location(tty, x, true);
 }
 
 
--- a/hotspot/src/share/vm/utilities/exceptions.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -117,7 +117,7 @@
                   (address)h_exception(), file, line, thread);
   }
   // for AbortVMOnException flag
-  NOT_PRODUCT(Exceptions::debug_check_abort(h_exception));
+  NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
 
   // Check for special boot-strapping/vm-thread handling
   if (special_exception(thread, file, line, h_exception)) return;
@@ -375,17 +375,26 @@
 
 #ifndef PRODUCT
 // caller frees value_string if necessary
-void Exceptions::debug_check_abort(const char *value_string) {
+void Exceptions::debug_check_abort(const char *value_string, const char* message) {
   if (AbortVMOnException != NULL && value_string != NULL &&
       strstr(value_string, AbortVMOnException)) {
-    fatal(err_msg("Saw %s, aborting", value_string));
+    if (AbortVMOnExceptionMessage == NULL || message == NULL ||
+        strcmp(message, AbortVMOnExceptionMessage) == 0) {
+      fatal(err_msg("Saw %s, aborting", value_string));
+    }
   }
 }
 
-void Exceptions::debug_check_abort(Handle exception) {
+void Exceptions::debug_check_abort(Handle exception, const char* message) {
   if (AbortVMOnException != NULL) {
     ResourceMark rm;
-    debug_check_abort(instanceKlass::cast(exception()->klass())->external_name());
+    if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) {
+      oop msg = java_lang_Throwable::message(exception);
+      if (msg != NULL) {
+        message = java_lang_String::as_utf8_string(msg);
+      }
+    }
+    debug_check_abort(instanceKlass::cast(exception()->klass())->external_name(), message);
   }
 }
 #endif
--- a/hotspot/src/share/vm/utilities/exceptions.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -143,8 +143,8 @@
   static void throw_stack_overflow_exception(Thread* thread, const char* file, int line);
 
   // for AbortVMOnException flag
-  NOT_PRODUCT(static void debug_check_abort(Handle exception);)
-  NOT_PRODUCT(static void debug_check_abort(const char *value_string);)
+  NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);)
+  NOT_PRODUCT(static void debug_check_abort(const char *value_string, const char* message = NULL);)
 };
 
 
--- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -216,8 +216,16 @@
 
 #define DEBUG_EXCEPTION ::abort();
 
+#ifdef ARM
+#ifdef SOLARIS
+#define BREAKPOINT __asm__ volatile (".long 0xe1200070")
+#else
+#define BREAKPOINT __asm__ volatile (".long 0xe7f001f0")
+#endif
+#else
 extern "C" void breakpoint();
 #define BREAKPOINT ::breakpoint()
+#endif
 
 // checking for nanness
 #ifdef SOLARIS
@@ -235,6 +243,12 @@
 #error "missing platform-specific definition here"
 #endif
 
+// GCC 4.3 does not allow 0.0/0.0 to produce a NAN value
+#if (__GNUC__ == 4) && (__GNUC_MINOR__ > 2)
+#define CAN_USE_NAN_DEFINE 1
+#endif
+
+
 // Checking for finiteness
 
 inline int g_isfinite(jfloat  f)                 { return finite(f); }
--- a/hotspot/src/share/vm/utilities/growableArray.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -97,7 +97,10 @@
     assert(_len >= 0 && _len <= _max, "initial_len too big");
     _arena = (c_heap ? (Arena*)1 : NULL);
     set_nesting();
-    assert(!c_heap || allocated_on_C_heap(), "growable array must be on C heap if elements are");
+    assert(!on_C_heap() || allocated_on_C_heap(), "growable array must be on C heap if elements are");
+    assert(!on_stack() ||
+           (allocated_on_res_area() || allocated_on_stack()),
+           "growable array must be on stack if elements are not on arena and not on C heap");
   }
 
   // This GA will use the given arena for storage.
@@ -108,6 +111,10 @@
     assert(_len >= 0 && _len <= _max, "initial_len too big");
     _arena = arena;
     assert(on_arena(), "arena has taken on reserved value 0 or 1");
+    // Relax next assert to allow object allocation on resource area,
+    // on stack or embedded into an other object.
+    assert(allocated_on_arena() || allocated_on_stack(),
+           "growable array must be on arena or on stack if elements are on arena");
   }
 
   void* raw_allocate(int elementSize);
--- a/hotspot/src/share/vm/utilities/macros.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/macros.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -151,9 +151,11 @@
 #if defined(IA32) || defined(AMD64)
 #define X86
 #define X86_ONLY(code) code
+#define NOT_X86(code)
 #else
 #undef X86
 #define X86_ONLY(code)
+#define NOT_X86(code) code
 #endif
 
 #ifdef IA32
@@ -188,4 +190,37 @@
 #define NOT_SPARC(code) code
 #endif
 
+#ifdef PPC
+#define PPC_ONLY(code) code
+#define NOT_PPC(code)
+#else
+#define PPC_ONLY(code)
+#define NOT_PPC(code) code
+#endif
+
+#ifdef E500V2
+#define E500V2_ONLY(code) code
+#define NOT_E500V2(code)
+#else
+#define E500V2_ONLY(code)
+#define NOT_E500V2(code) code
+#endif
+
+
+#ifdef ARM
+#define ARM_ONLY(code) code
+#define NOT_ARM(code)
+#else
+#define ARM_ONLY(code)
+#define NOT_ARM(code) code
+#endif
+
+#ifdef JAVASE_EMBEDDED
+#define EMBEDDED_ONLY(code) code
+#define NOT_EMBEDDED(code)
+#else
+#define EMBEDDED_ONLY(code)
+#define NOT_EMBEDDED(code) code
+#endif
+
 #define define_pd_global(type, name, value) const type pd_##name = value;
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Thu Sep 02 12:17:21 2010 -0700
@@ -479,8 +479,8 @@
 
        if (fr.sp()) {
          st->print(",  sp=" PTR_FORMAT, fr.sp());
-         st->print(",  free space=%" INTPTR_FORMAT "k",
-                     ((intptr_t)fr.sp() - (intptr_t)stack_bottom) >> 10);
+         size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024);
+         st->print(",  free space=" SIZE_FORMAT "k", free_stack_size);
        }
 
        st->cr();
@@ -687,16 +687,13 @@
 # undef END
 }
 
+VMError* volatile VMError::first_error = NULL;
+volatile jlong VMError::first_error_tid = -1;
 
 void VMError::report_and_die() {
   // Don't allocate large buffer on stack
   static char buffer[O_BUFLEN];
 
-  // First error, and its thread id. We must be able to handle native thread,
-  // so use thread id instead of Thread* to identify thread.
-  static VMError* first_error;
-  static jlong    first_error_tid;
-
   // An error could happen before tty is initialized or after it has been
   // destroyed. Here we use a very simple unbuffered fdStream for printing.
   // Only out.print_raw() and out.print_raw_cr() should be used, as other
--- a/hotspot/src/share/vm/utilities/vmError.hpp	Tue Aug 31 15:05:09 2010 +0400
+++ b/hotspot/src/share/vm/utilities/vmError.hpp	Thu Sep 02 12:17:21 2010 -0700
@@ -57,6 +57,10 @@
   int          _current_step;
   const char * _current_step_info;
   int          _verbose;
+  // First error, and its thread id. We must be able to handle native thread,
+  // so use thread id instead of Thread* to identify thread.
+  static VMError* volatile first_error;
+  static volatile jlong    first_error_tid;
 
   // used by reporting about OOM
   size_t       _size;
@@ -108,4 +112,7 @@
   // returns original handler for signal, if it was resetted, or NULL if
   // signal was not changed by error reporter
   static address get_resetted_sighandler(int sig);
+
+  // check to see if fatal error reporting is in progress
+  static bool fatal_error_in_progress() { return first_error != NULL; }
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6973329/Test.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6973329
+ * @summary C2 with Zero based COOP produces code with broken anti-dependency on x86
+ *
+ * @run main/othervm -Xbatch -Xcomp -XX:CompileOnly=Test Test
+ */
+
+class A {
+  A next;
+  int n;
+
+  public int get_n() {
+    return n+1;
+  }
+}
+public class Test {
+
+  A a;
+
+  void test (A new_next) {
+    A prev_next = a.next;
+    a.next = new_next;
+    if (prev_next == null) {
+      a.n = a.get_n();
+    }
+  }
+
+  public static void main(String args[]) {
+    Test t = new Test();
+    t.a = new A();
+    t.a.n = 1;
+    t.test(new A());
+    if (t.a.n != 2) {
+      System.out.println("Wrong value: " + t.a.n + " expected: 2");
+      System.exit(97);
+    }
+  }
+}
+
--- a/jaxp/.hgtags	Tue Aug 31 15:05:09 2010 +0400
+++ b/jaxp/.hgtags	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
 15573625af97d01c4e24549041cba7584da7fe88 jdk7-b102
 b7722e8788644507c10bb69a137de422d0300b24 jdk7-b103
 d42c4acb6424a094bdafe2ad9c8c1c7ca7fb7b7e jdk7-b104
+3233b9a4c12ef2663a356d08bb141c02736c7f49 jdk7-b105
+5ba8469212a6cab95ca652eea414b753be7d245a jdk7-b106
+20ee37c1372a3eaefa49b426c6eb68a2e8f5d6e2 jdk7-b107
--- a/jaxws/.hgtags	Tue Aug 31 15:05:09 2010 +0400
+++ b/jaxws/.hgtags	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
 d8580443d1815d68e0035a0560634e50fa899288 jdk7-b102
 267386d6b923f724309cab855a555e2d86a15c8f jdk7-b103
 bbc4cce6c20aeca4862804a6e8315a2350d43633 jdk7-b104
+39eb4f3031f4a985664cace00fca3bd1eab1e0aa jdk7-b105
+bc45ccc5bcca6cbe4ea433e279d4a93b06ab38c6 jdk7-b106
+017612ea6af417a5e378619704da01bb3a583bdb jdk7-b107
--- a/jdk/.hgtags	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/.hgtags	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
 13029a61b16bec06535d4f0aa98229b358684128 jdk7-b102
 6488b70a23cc6dc4b7e00809bc503c2884bafb28 jdk7-b103
 1a92820132a0221c5bdedd42d0888c57ce4cbb34 jdk7-b104
+3b0abcb512807bb6f6d27755bc50103211bde6ee jdk7-b105
+b91ef6b60f4e19bf4592c6dd594c9bac62487519 jdk7-b106
+882103f334bb23745d3fd70fb7928c347478b0f4 jdk7-b107
--- a/jdk/make/common/shared/Defs-windows.gmk	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/common/shared/Defs-windows.gmk	Thu Sep 02 12:17:21 2010 -0700
@@ -89,7 +89,7 @@
 $(shell $(CYGPATH_CMD) $1 2> $(DEV_NULL))
 endef
 define OptFullPath
-$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1"; else echo "$1"; fi)
+$(shell if [ "$1" != "" -a -d "$1" ]; then $(CYGPATH_CMD) "$1" 2> $(DEV_NULL); else echo "$1"; fi)
 endef
 else
 # Temporary until we upgrade to MKS 8.7, MKS pwd returns mixed mode path
--- a/jdk/make/common/shared/Defs.gmk	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/common/shared/Defs.gmk	Thu Sep 02 12:17:21 2010 -0700
@@ -136,15 +136,20 @@
 $(shell echo $1 | sed -e 's@[^0-9]*\([0-9][0-9]*\.[0-9][.0-9]*\).*@\1@' )
 endef
 
+# Return one part of the version numbers, watch out for non digits.
+define VersionWord # Number Version
+$(word $1,$(subst ., ,$(subst -, ,$2)))
+endef
+
 # Given a major.minor.micro version, return the major, minor, or micro number
 define MajorVersion
-$(if $(word 1, $(subst ., ,$1)),$(word 1, $(subst ., ,$1)),0)
+$(if $(call VersionWord,1,$1),$(call VersionWord,1,$1),0)
 endef
 define MinorVersion
-$(if $(word 2, $(subst ., ,$1)),$(word 2, $(subst ., ,$1)),0)
+$(if $(call VersionWord,2,$1),$(call VersionWord,2,$1),0)
 endef
 define MicroVersion
-$(if $(word 3, $(subst ., ,$1)),$(word 3, $(subst ., ,$1)),0)
+$(if $(call VersionWord,3,$1),$(call VersionWord,3,$1),0)
 endef
 
 # Macro that returns missing, same, newer, or older $1=version $2=required
--- a/jdk/make/jdk_generic_profile.sh	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/jdk_generic_profile.sh	Thu Sep 02 12:17:21 2010 -0700
@@ -340,6 +340,10 @@
 export PATH
 
 # Export variables required for Zero
+if [ "${SHARK_BUILD}" = true ] ; then
+  ZERO_BUILD=true
+  export ZERO_BUILD
+fi
 if [ "${ZERO_BUILD}" = true ] ; then
   # ZERO_LIBARCH is the name of the architecture-specific
   # subdirectory under $JAVA_HOME/jre/lib
@@ -417,4 +421,55 @@
   fi
   export LIBFFI_CFLAGS
   export LIBFFI_LIBS
+
+  # LLVM_CFLAGS, LLVM_LDFLAGS and LLVM_LIBS tell the compiler how to
+  # compile and link against LLVM
+  if [ "${SHARK_BUILD}" = true ] ; then
+    if [ "${LLVM_CONFIG}" = "" ] ; then
+      LLVM_CONFIG=$(which llvm-config 2>/dev/null)
+    fi
+    if [ ! -x "${LLVM_CONFIG}" ] ; then
+      echo "ERROR: Unable to locate llvm-config"
+      exit 1
+    fi
+    llvm_components="jit engine nativecodegen"
+
+    unset LLVM_CFLAGS
+    for flag in $("${LLVM_CONFIG}" --cxxflags $llvm_components); do
+      if echo "${flag}" | grep -q '^-[ID]'; then
+        if [ "${flag}" != "-D_DEBUG" ] ; then
+          if [ "${LLVM_CFLAGS}" != "" ] ; then
+            LLVM_CFLAGS="${LLVM_CFLAGS} "
+          fi
+          LLVM_CFLAGS="${LLVM_CFLAGS}${flag}"
+        fi
+      fi
+    done
+    llvm_version=$("${LLVM_CONFIG}" --version | sed 's/\.//; s/svn.*//')
+    LLVM_CFLAGS="${LLVM_CFLAGS} -DSHARK_LLVM_VERSION=${llvm_version}"
+
+    unset LLVM_LDFLAGS
+    for flag in $("${LLVM_CONFIG}" --ldflags $llvm_components); do
+      if echo "${flag}" | grep -q '^-L'; then
+        if [ "${LLVM_LDFLAGS}" != "" ] ; then
+          LLVM_LDFLAGS="${LLVM_LDFLAGS} "
+        fi
+        LLVM_LDFLAGS="${LLVM_LDFLAGS}${flag}"
+      fi
+    done
+
+    unset LLVM_LIBS
+    for flag in $("${LLVM_CONFIG}" --libs $llvm_components); do
+      if echo "${flag}" | grep -q '^-l'; then
+        if [ "${LLVM_LIBS}" != "" ] ; then
+          LLVM_LIBS="${LLVM_LIBS} "
+        fi
+        LLVM_LIBS="${LLVM_LIBS}${flag}"
+      fi
+    done
+
+    export LLVM_CFLAGS
+    export LLVM_LDFLAGS
+    export LLVM_LIBS
+  fi
 fi
--- a/jdk/make/sun/javazic/tzdata/VERSION	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/VERSION	Thu Sep 02 12:17:21 2010 -0700
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2010i
+tzdata2010l
--- a/jdk/make/sun/javazic/tzdata/africa	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/africa	Thu Sep 02 12:17:21 2010 -0700
@@ -316,8 +316,25 @@
 # and can be found by searching for "winter" in their search engine
 # (at least today).
 
+# From Alexander Krivenyshev (2010-07-20):
+# According to News from Egypt -  Al-Masry Al-Youm Egypt's cabinet has
+# decided that Daylight Saving Time will not be used in Egypt during
+# Ramadan.
+#
+# Arabic translation:
+# "Clocks to go back during Ramadan--and then forward again"
+# <a href="http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again">
+# http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_egypt02.html
+# </a>
+
 Rule	Egypt	2008	only	-	Aug	lastThu	23:00s	0	-
 Rule	Egypt	2009	only	-	Aug	20	23:00s	0	-
+Rule	Egypt	2010	only	-	Aug	11	0:00	0	-
+Rule	Egypt	2010	only	-	Sep	10	0:00	1:00	S
 Rule	Egypt	2010	max	-	Sep	lastThu	23:00s	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
--- a/jdk/make/sun/javazic/tzdata/asia	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/asia	Thu Sep 02 12:17:21 2010 -0700
@@ -2200,6 +2200,18 @@
 # "At 12:01am Friday, clocks in Israel and the West Bank will change to
 # 1:01am, while Gaza clocks will change at 12:01am Saturday morning."
 
+# From Steffen Thorsen (2010-08-11):
+# According to several sources, including
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=306795">
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=306795
+# </a>
+# the clocks were set back one hour at 2010-08-11 00:00:00 local time in 
+# Gaza and the West Bank.
+# Some more background info:
+# <a href="http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html">
+# http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html
+# </a>
+
 # The rules for Egypt are stolen from the `africa' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -2220,6 +2232,7 @@
 Rule Palestine	2009	only	-	Mar	lastFri	0:00	1:00	S
 Rule Palestine	2010	max	-	Mar	lastSat	0:01	1:00	S
 Rule Palestine	2009	max	-	Sep	Fri>=1	2:00	0	-
+Rule Palestine	2010	only	-	Aug	11	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
--- a/jdk/make/sun/javazic/tzdata/australasia	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/australasia	Thu Sep 02 12:17:21 2010 -0700
@@ -368,10 +368,10 @@
 
 # Micronesia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Truk	10:07:08 -	LMT	1901
-			10:00	-	TRUT			# Truk Time
-Zone Pacific/Ponape	10:32:52 -	LMT	1901		# Kolonia
-			11:00	-	PONT			# Ponape Time
+Zone Pacific/Chuuk	10:07:08 -	LMT	1901
+			10:00	-	CHUT			# Chuuk Time
+Zone Pacific/Pohnpei	10:32:52 -	LMT	1901		# Kolonia
+			11:00	-	PONT			# Pohnpei Time
 Zone Pacific/Kosrae	10:51:56 -	LMT	1901
 			11:00	-	KOST	1969 Oct	# Kosrae Time
 			12:00	-	KOST	1999
--- a/jdk/make/sun/javazic/tzdata/backward	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/backward	Thu Sep 02 12:17:21 2010 -0700
@@ -112,7 +112,9 @@
 Link	America/Denver		Navajo
 Link	Asia/Shanghai		PRC
 Link	Pacific/Pago_Pago	Pacific/Samoa
-Link	Pacific/Truk		Pacific/Yap
+Link	Pacific/Chuuk		Pacific/Yap
+Link	Pacific/Chuuk		Pacific/Truk
+Link	Pacific/Pohnpei		Pacific/Ponape
 Link	Europe/Warsaw		Poland
 Link	Europe/Lisbon		Portugal
 Link	Asia/Taipei		ROC
--- a/jdk/make/sun/javazic/tzdata/europe	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/europe	Thu Sep 02 12:17:21 2010 -0700
@@ -1035,22 +1035,47 @@
 			2:00	EU	EE%sT
 
 # Finland
-#
+
 # From Hannu Strang (1994-09-25 06:03:37 UTC):
 # Well, here in Helsinki we're just changing from summer time to regular one,
 # and it's supposed to change at 4am...
+
+# From Janne Snabb (2010-0715):
 #
-# From Paul Eggert (2006-03-22):
-# Shanks & Pottenger say Finland has switched at 02:00 standard time
-# since 1981.  Go with Strang instead.
+# I noticed that the Finland data is not accurate for years 1981 and 1982.
+# During these two first trial years the DST adjustment was made one hour
+# earlier than in forthcoming years. Starting 1983 the adjustment was made
+# according to the central European standards.
+#
+# This is documented in Heikki Oja: Aikakirja 2007, published by The Almanac
+# Office of University of Helsinki, ISBN 952-10-3221-9, available online (in
+# Finnish) at
+#
+# <a href="http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf">
+# http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf
+# </a>
 #
+# Page 105 (56 in PDF version) has a handy table of all past daylight savings
+# transitions. It is easy enough to interpret without Finnish skills.
+#
+# This is also confirmed by Finnish Broadcasting Company's archive at:
+#
+# <a href="http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401">
+# http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401
+# </a>
+#
+# The news clip from 1981 says that "the time between 2 and 3 o'clock does not
+# exist tonight."
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Finland	1942	only	-	Apr	3	0:00	1:00	S
 Rule	Finland	1942	only	-	Oct	3	0:00	0	-
+Rule	Finland	1981	1982	-	Mar	lastSun	2:00	1:00	S
+Rule	Finland	1981	1982	-	Sep	lastSun	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Helsinki	1:39:52 -	LMT	1878 May 31
 			1:39:52	-	HMT	1921 May    # Helsinki Mean Time
-			2:00	Finland	EE%sT	1981 Mar 29 2:00
+			2:00	Finland	EE%sT	1983
 			2:00	EU	EE%sT
 
 # Aaland Is
--- a/jdk/make/sun/javazic/tzdata/leapseconds	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/leapseconds	Thu Sep 02 12:17:21 2010 -0700
@@ -82,9 +82,9 @@
 # FAX       : 33 (0) 1 40 51 22 91
 # Internet  : services.iers@obspm.fr
 #
-# Paris, 4 July 2009
+# Paris, 14 July 2010
 #
-# Bulletin C 38
+# Bulletin C 40
 #
 # To authorities responsible
 # for the measurement and
@@ -92,9 +92,9 @@
 #
 # INFORMATION ON UTC - TAI
 #
-# NO positive leap second will be introduced at the end of December 2009.
+# NO positive leap second will be introduced at the end of December 2010.
 # The difference between Coordinated Universal Time UTC and the
-# International Atomic Time TAI is :		
+# International Atomic Time TAI is :
 #
 # from 2009 January 1, 0h UTC, until further notice : UTC-TAI = -34 s
 #
@@ -104,6 +104,6 @@
 # will be no time step at the next possible date.
 #
 # Daniel GAMBIS
-# Director			
+# Director
 # Earth Orientation Center of IERS
 # Observatoire de Paris, France
--- a/jdk/make/sun/javazic/tzdata/northamerica	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/northamerica	Thu Sep 02 12:17:21 2010 -0700
@@ -1346,6 +1346,83 @@
 # entry since our cutoff date of 1970, so we can move
 # America/Coral_Harbour to the 'backward' file.
 
+# From Mark Brader (2010-03-06):
+#
+# Currently the database has:
+#
+# # Ontario
+#
+# # From Paul Eggert (2006-07-09):
+# # Shanks & Pottenger write that since 1970 most of Ontario has been like
+# # Toronto.
+# # Thunder Bay skipped DST in 1973.
+# # Many smaller locales did not observe peacetime DST until 1974;
+# # Nipigon (EST) and Rainy River (CST) are the largest that we know of.
+#
+# In the (Toronto) Globe and Mail for Saturday, 1955-09-24, in the bottom
+# right corner of page 1, it says that Toronto will return to standard
+# time at 2 am Sunday morning (which agrees with the database), and that:
+#
+#     The one-hour setback will go into effect throughout most of Ontario,
+#     except in areas like Windsor which remains on standard time all year.
+#
+# Windsor is, of course, a lot larger than Nipigon.
+#
+# I only came across this incidentally.  I don't know if Windsor began
+# observing DST when Detroit did, or in 1974, or on some other date.
+#
+# By the way, the article continues by noting that:
+#
+#     Some cities in the United States have pushed the deadline back
+#     three weeks and will change over from daylight saving in October.
+
+# From Arthur David Olson (2010-07-17):
+#
+# "Standard Time and Time Zones in Canada" appeared in
+# The Journal of The Royal Astronomical Society of Canada,
+# volume 26, number 2 (February 1932) and, as of 2010-07-17,
+# was available at
+# <a href="http://adsabs.harvard.edu/full/1932JRASC..26...49S">
+# http://adsabs.harvard.edu/full/1932JRASC..26...49S
+# </a>
+#
+# It includes the text below (starting on page 57):
+#
+#   A list of the places in Canada using daylight saving time would
+# require yearly revision. From information kindly furnished by
+# the provincial governments and by the postmasters in many cities
+# and towns, it is found that the following places used daylight sav-
+# ing in 1930. The information for the province of Quebec is definite,
+# for the other provinces only approximate:
+#
+# 	Province	Daylight saving time used
+# Prince Edward Island	Not used.
+# Nova Scotia		In Halifax only.
+# New Brunswick		In St. John only.
+# Quebec		In the following places:
+# 			Montreal	Lachine
+# 			Quebec		Mont-Royal
+# 			Levis		Iberville
+# 			St. Lambert	Cap de la Madeleine
+# 			Verdun		Loretteville
+# 			Westmount	Richmond
+# 			Outremont	St. Jerome
+# 			Longueuil	Greenfield Park
+# 			Arvida		Waterloo
+# 			Chambly-Canton	Beaulieu
+# 			Melbourne	La Tuque
+# 			St. Theophile	Buckingham
+# Ontario		Used generally in the cities and towns along
+# 			the southerly part of the province. Not
+# 			used in the northwesterlhy part.
+# Manitoba		Not used.
+# Saskatchewan		In Regina only.
+# Alberta		Not used.
+# British Columbia	Not used.
+#
+#   With some exceptions, the use of daylight saving may be said to be limited
+# to those cities and towns lying between Quebec city and Windsor, Ont.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Toronto	1919	only	-	Mar	30	23:30	1:00	D
 Rule	Toronto	1919	only	-	Oct	26	0:00	0	S
@@ -2111,7 +2188,44 @@
 			-8:00	-	PST	1970
 			-7:00	Mexico	M%sT	1999
 			-7:00	-	MST
+
+# From Alexander Krivenyshev (2010-04-21):
+# According to news, Bah&iacute;a de Banderas (Mexican state of Nayarit)
+# changed time zone UTC-7 to new time zone UTC-6 on April 4, 2010 (to
+# share the same time zone as nearby city Puerto Vallarta, Jalisco).
+#
+# (Spanish)
+# Bah&iacute;a de Banderas homologa su horario al del centro del
+# pa&iacute;s, a partir de este domingo
+# <a href="http://www.nayarit.gob.mx/notes.asp?id=20748">
+# http://www.nayarit.gob.mx/notes.asp?id=20748
+# </a>
+#
+# Bah&iacute;a de Banderas homologa su horario con el del Centro del
+# Pa&iacute;s
+# <a href="http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50">
+# http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50"
+# </a>
+#
+# (English)
+# Puerto Vallarta and Bah&iacute;a de Banderas: One Time Zone
+# <a href="http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml">
+# http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml
+# </a>
+#
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_mexico08.html">
+# http://www.worldtimezone.com/dst_news/dst_news_mexico08.html
+# </a>
+#
+# "Mexico's Senate approved the amendments to the Mexican Schedule System that
+# will allow Bah&iacute;a de Banderas and Puerto Vallarta to share the same time
+# zone ..."
 # Baja California Sur, Nayarit, Sinaloa
+
+# From Arthur David Olson (2010-05-01):
+# Use "Bahia_Banderas" to keep the name to fourteen characters.
+
 Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
 			-7:00	-	MST	1927 Jun 10 23:00
 			-6:00	-	CST	1930 Nov 15
@@ -2122,6 +2236,19 @@
 			-7:00	-	MST	1949 Jan 14
 			-8:00	-	PST	1970
 			-7:00	Mexico	M%sT
+
+Zone America/Bahia_Banderas	-7:01:00 -	LMT	1921 Dec 31 23:59:00
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT	2010 Apr 4 2:00
+			-6:00	Mexico	C%sT
+
 # Baja California (near US border)
 Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
 			-7:00	-	MST	1924
--- a/jdk/make/sun/javazic/tzdata/zone.tab	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/make/sun/javazic/tzdata/zone.tab	Thu Sep 02 12:17:21 2010 -0700
@@ -199,8 +199,8 @@
 FI	+6010+02458	Europe/Helsinki
 FJ	-1808+17825	Pacific/Fiji
 FK	-5142-05751	Atlantic/Stanley
-FM	+0725+15147	Pacific/Truk	Truk (Chuuk) and Yap
-FM	+0658+15813	Pacific/Ponape	Ponape (Pohnpei)
+FM	+0725+15147	Pacific/Chuuk	Chuuk (Truk) and Yap
+FM	+0658+15813	Pacific/Pohnpei	Pohnpei (Ponape)
 FM	+0519+16259	Pacific/Kosrae	Kosrae
 FO	+6201-00646	Atlantic/Faroe
 FR	+4852+00220	Europe/Paris
@@ -310,6 +310,7 @@
 MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
 MX	+3232-11701	America/Tijuana	US Pacific Time - Baja California near US border
 MX	+3018-11452	America/Santa_Isabel	Mexican Pacific Time - Baja California away from US border
+MX	+2048-10515	America/Bahia_Banderas	Mexican Central Time - Bahia de Banderas
 MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
 MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
 MZ	-2558+03235	Africa/Maputo
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -27,7 +27,6 @@
 
 import java.io.*;
 import java.util.*;
-import com.sun.java.util.jar.pack.Package.Class;
 import com.sun.java.util.jar.pack.ConstantPool.*;
 
 /**
@@ -96,20 +95,20 @@
         return this.def.compareTo(that.def);
     }
 
-    static private final byte[] noBytes = {};
-    static private final HashMap canonLists = new HashMap();
-    static private final HashMap attributes = new HashMap();
-    static private final HashMap standardDefs = new HashMap();
+    private static final byte[] noBytes = {};
+    private static final Map<List<Attribute>, List<Attribute>> canonLists = new HashMap<>();
+    private static final Map<Layout, Attribute> attributes = new HashMap<>();
+    private static final Map<Layout, Attribute> standardDefs = new HashMap<>();
 
     // Canonicalized lists of trivial attrs (Deprecated, etc.)
     // are used by trimToSize, in order to reduce footprint
     // of some common cases.  (Note that Code attributes are
     // always zero size.)
-    public static List getCanonList(List al) {
+    public static List getCanonList(List<Attribute> al) {
         synchronized (canonLists) {
-            List cl = (List) canonLists.get(al);
+            List<Attribute> cl = canonLists.get(al);
             if (cl == null) {
-                cl = new ArrayList(al.size());
+                cl = new ArrayList<>(al.size());
                 cl.addAll(al);
                 cl = Collections.unmodifiableList(cl);
                 canonLists.put(al, cl);
@@ -122,7 +121,7 @@
     public static Attribute find(int ctype, String name, String layout) {
         Layout key = Layout.makeKey(ctype, name, layout);
         synchronized (attributes) {
-            Attribute a = (Attribute) attributes.get(key);
+            Attribute a = attributes.get(key);
             if (a == null) {
                 a = new Layout(ctype, name, layout).canonicalInstance();
                 attributes.put(key, a);
@@ -131,24 +130,29 @@
         }
     }
 
-    public static Object keyForLookup(int ctype, String name) {
+    public static Layout keyForLookup(int ctype, String name) {
         return Layout.makeKey(ctype, name);
     }
 
     // Find canonical empty attribute with given ctype and name,
     // and with the standard layout.
-    public static Attribute lookup(Map defs, int ctype, String name) {
-        if (defs == null)  defs = standardDefs;
-        return (Attribute) defs.get(Layout.makeKey(ctype, name));
+    public static Attribute lookup(Map<Layout, Attribute> defs, int ctype,
+            String name) {
+        if (defs == null) {
+            defs = standardDefs;
+        }
+        return defs.get(Layout.makeKey(ctype, name));
     }
-    public static Attribute define(Map defs, int ctype, String name, String layout) {
+
+    public static Attribute define(Map<Layout, Attribute> defs, int ctype,
+            String name, String layout) {
         Attribute a = find(ctype, name, layout);
         defs.put(Layout.makeKey(ctype, name), a);
         return a;
     }
 
     static {
-        Map sd = standardDefs;
+        Map<Layout, Attribute> sd = standardDefs;
         define(sd, ATTR_CONTEXT_CLASS, "Signature", "RSH");
         define(sd, ATTR_CONTEXT_CLASS, "Synthetic", "");
         define(sd, ATTR_CONTEXT_CLASS, "Deprecated", "");
@@ -244,7 +248,7 @@
              +"\n    ()[] ]"
              )
         };
-        Map sd = standardDefs;
+        Map<Layout, Attribute> sd = standardDefs;
         String defaultLayout     = mdLayouts[2];
         String annotationsLayout = mdLayouts[1] + mdLayouts[2];
         String paramsLayout      = mdLayouts[0] + annotationsLayout;
@@ -275,10 +279,6 @@
         return null;
     }
 
-    public static Map getStandardDefs() {
-        return new HashMap(standardDefs);
-    }
-
     /** Base class for any attributed object (Class, Field, Method, Code).
      *  Flags are included because they are used to help transmit the
      *  presence of attributes.  That is, flags are a mix of modifier
@@ -291,7 +291,7 @@
         protected abstract Entry[] getCPMap();
 
         protected int flags;             // defined here for convenience
-        protected List attributes;
+        protected List<Attribute> attributes;
 
         public int attributeSize() {
             return (attributes == null) ? 0 : attributes.size();
@@ -301,16 +301,15 @@
             if (attributes == null) {
                 return;
             }
-            if (attributes.size() == 0) {
+            if (attributes.isEmpty()) {
                 attributes = null;
                 return;
             }
             if (attributes instanceof ArrayList) {
-                ArrayList al = (ArrayList) attributes;
+                ArrayList<Attribute> al = (ArrayList<Attribute>)attributes;
                 al.trimToSize();
                 boolean allCanon = true;
-                for (Iterator i = al.iterator(); i.hasNext(); ) {
-                    Attribute a = (Attribute) i.next();
+                for (Attribute a : al) {
                     if (!a.isCanonical()) {
                         allCanon = false;
                     }
@@ -330,9 +329,9 @@
 
         public void addAttribute(Attribute a) {
             if (attributes == null)
-                attributes = new ArrayList(3);
+                attributes = new ArrayList<>(3);
             else if (!(attributes instanceof ArrayList))
-                attributes = new ArrayList(attributes);  // unfreeze it
+                attributes = new ArrayList<>(attributes);  // unfreeze it
             attributes.add(a);
         }
 
@@ -340,32 +339,31 @@
             if (attributes == null)       return null;
             if (!attributes.contains(a))  return null;
             if (!(attributes instanceof ArrayList))
-                attributes = new ArrayList(attributes);  // unfreeze it
+                attributes = new ArrayList<>(attributes);  // unfreeze it
             attributes.remove(a);
             return a;
         }
 
         public Attribute getAttribute(int n) {
-            return (Attribute) attributes.get(n);
+            return attributes.get(n);
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             if (attributes == null)  return;
-            for (Iterator i = attributes.iterator(); i.hasNext(); ) {
-                Attribute a = (Attribute) i.next();
+            for (Attribute a : attributes) {
                 a.visitRefs(this, mode, refs);
             }
         }
 
-        static final List noAttributes = Arrays.asList(new Object[0]);
+        static final List<Attribute> noAttributes = Arrays.asList(new Attribute[0]);
 
-        public List getAttributes() {
+        public List<Attribute> getAttributes() {
             if (attributes == null)
                 return noAttributes;
             return attributes;
         }
 
-        public void setAttributes(List attrList) {
+        public void setAttributes(List<Attribute> attrList) {
             if (attrList.isEmpty())
                 attributes = null;
             else
@@ -374,8 +372,7 @@
 
         public Attribute getAttribute(String attrName) {
             if (attributes == null)  return null;
-            for (Iterator i = attributes.iterator(); i.hasNext(); ) {
-                Attribute a = (Attribute) i.next();
+            for (Attribute a : attributes) {
                 if (a.name().equals(attrName))
                     return a;
             }
@@ -384,8 +381,7 @@
 
         public Attribute getAttribute(Layout attrDef) {
             if (attributes == null)  return null;
-            for (Iterator i = attributes.iterator(); i.hasNext(); ) {
-                Attribute a = (Attribute) i.next();
+            for (Attribute a : attributes) {
                 if (a.layout() == attrDef)
                     return a;
             }
@@ -457,14 +453,8 @@
         public String layout() { return layout; }
         public Attribute canonicalInstance() { return canon; }
 
-        // Cache of name reference.
-        private Entry nameRef;   // name, for use by visitRefs
         public Entry getNameRef() {
-            Entry nameRef = this.nameRef;
-            if (nameRef == null) {
-                this.nameRef = nameRef = ConstantPool.getUtf8Entry(name());
-            }
-            return nameRef;
+            return ConstantPool.getUtf8Entry(name());
         }
 
         public boolean isEmpty() { return layout == ""; }
@@ -834,14 +824,14 @@
     */
     static //private
     Layout.Element[] tokenizeLayout(Layout self, int curCble, String layout) {
-        ArrayList col = new ArrayList(layout.length());
+        ArrayList<Layout.Element> col = new ArrayList<>(layout.length());
         tokenizeLayout(self, curCble, layout, col);
         Layout.Element[] res = new Layout.Element[col.size()];
         col.toArray(res);
         return res;
     }
     static //private
-    void tokenizeLayout(Layout self, int curCble, String layout, ArrayList col) {
+    void tokenizeLayout(Layout self, int curCble, String layout, ArrayList<Layout.Element> col) {
         boolean prevBCI = false;
         for (int len = layout.length(), i = 0; i < len; ) {
             int start = i;
@@ -899,7 +889,7 @@
             case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
                 kind = EK_UN;
                 i = tokenizeSInt(e, layout, i);
-                ArrayList cases = new ArrayList();
+                ArrayList<Layout.Element> cases = new ArrayList<>();
                 for (;;) {
                     // Keep parsing cases until we hit the default case.
                     if (layout.charAt(i++) != '(')
@@ -1053,7 +1043,7 @@
     }
     static //private
     String[] splitBodies(String layout) {
-        ArrayList bodies = new ArrayList();
+        ArrayList<String> bodies = new ArrayList<>();
         // Parse several independent layout bodies:  "[foo][bar]...[baz]"
         for (int i = 0; i < layout.length(); i++) {
             if (layout.charAt(i++) != '[')
@@ -1132,7 +1122,9 @@
     int parseIntBefore(String layout, int dash) {
         int end = dash;
         int beg = end;
-        while (beg > 0 && isDigit(layout.charAt(beg-1)))  --beg;
+        while (beg > 0 && isDigit(layout.charAt(beg-1))) {
+            --beg;
+        }
         if (beg == end)  return Integer.parseInt("empty");
         // skip backward over a sign
         if (beg >= 1 && layout.charAt(beg-1) == '-')  --beg;
@@ -1145,7 +1137,9 @@
         int end = beg;
         int limit = layout.length();
         if (end < limit && layout.charAt(end) == '-')  ++end;
-        while (end < limit && isDigit(layout.charAt(end)))  ++end;
+        while (end < limit && isDigit(layout.charAt(end))) {
+            ++end;
+        }
         if (beg == end)  return Integer.parseInt("empty");
         return Integer.parseInt(layout.substring(beg, end));
     }
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2003, 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
@@ -25,7 +25,6 @@
 
 package com.sun.java.util.jar.pack;
 
-import java.io.*;
 import java.util.*;
 
 /**
@@ -40,20 +39,13 @@
         return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
     }
 
-    // Uniquification tables for factory methods:
-    private static final HashMap utf8Entries       = new HashMap();
-    private static final HashMap classEntries      = new HashMap();
-    private static final HashMap literalEntries    = new HashMap();
-    private static final HashMap signatureEntries  = new HashMap();
-    private static final HashMap descriptorEntries = new HashMap();
-    private static final HashMap memberEntries     = new HashMap();
-
     /** Factory for Utf8 string constants.
      *  Used for well-known strings like "SourceFile", "<init>", etc.
      *  Also used to back up more complex constant pool entries, like Class.
      */
     public static synchronized Utf8Entry getUtf8Entry(String value) {
-        Utf8Entry e = (Utf8Entry) utf8Entries.get(value);
+        Map<String, Utf8Entry> utf8Entries  = Utils.getUtf8Entries();
+        Utf8Entry e = utf8Entries.get(value);
         if (e == null) {
             e = new Utf8Entry(value);
             utf8Entries.put(e.stringValue(), e);
@@ -62,9 +54,10 @@
     }
     /** Factory for Class constants. */
     public static synchronized ClassEntry getClassEntry(String name) {
-        ClassEntry e = (ClassEntry) classEntries.get(name);
+        Map<String, ClassEntry> classEntries = Utils.getClassEntries();
+        ClassEntry e = classEntries.get(name);
         if (e == null) {
-            e = (ClassEntry) new ClassEntry(getUtf8Entry(name));
+            e = new ClassEntry(getUtf8Entry(name));
             assert(name.equals(e.stringValue()));
             classEntries.put(e.stringValue(), e);
         }
@@ -72,7 +65,8 @@
     }
     /** Factory for literal constants (String, Integer, etc.). */
     public static synchronized LiteralEntry getLiteralEntry(Comparable value) {
-        LiteralEntry e = (LiteralEntry) literalEntries.get(value);
+        Map<Object, LiteralEntry> literalEntries = Utils.getLiteralEntries();
+        LiteralEntry e = literalEntries.get(value);
         if (e == null) {
             if (value instanceof String)
                 e = new StringEntry(getUtf8Entry((String)value));
@@ -89,7 +83,8 @@
 
     /** Factory for signature (type) constants. */
     public static synchronized SignatureEntry getSignatureEntry(String type) {
-        SignatureEntry e = (SignatureEntry) signatureEntries.get(type);
+        Map<String, SignatureEntry> signatureEntries = Utils.getSignatureEntries();
+        SignatureEntry e = signatureEntries.get(type);
         if (e == null) {
             e = new SignatureEntry(type);
             assert(e.stringValue().equals(type));
@@ -104,8 +99,9 @@
 
     /** Factory for descriptor (name-and-type) constants. */
     public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) {
+        Map<String, DescriptorEntry> descriptorEntries = Utils.getDescriptorEntries();
         String key = DescriptorEntry.stringValueOf(nameRef, typeRef);
-        DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key);
+        DescriptorEntry e = descriptorEntries.get(key);
         if (e == null) {
             e = new DescriptorEntry(nameRef, typeRef);
             assert(e.stringValue().equals(key))
@@ -121,8 +117,9 @@
 
     /** Factory for member reference constants. */
     public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
+        Map<String, MemberEntry> memberEntries = Utils.getMemberEntries();
         String key = MemberEntry.stringValueOf(tag, classRef, descRef);
-        MemberEntry e = (MemberEntry) memberEntries.get(key);
+        MemberEntry e = memberEntries.get(key);
         if (e == null) {
             e = new MemberEntry(tag, classRef, descRef);
             assert(e.stringValue().equals(key))
@@ -489,8 +486,9 @@
             String[] parts = structureSignature(value);
             formRef = getUtf8Entry(parts[0]);
             classRefs = new ClassEntry[parts.length-1];
-            for (int i = 1; i < parts.length; i++)
-                classRefs[i-1] = getClassEntry(parts[i]);
+            for (int i = 1; i < parts.length; i++) {
+                classRefs[i - 1] = getClassEntry(parts[i]);
+            }
             hashCode();  // force computation of valueHash
         }
         protected int computeValueHash() {
@@ -527,8 +525,9 @@
         String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) {
             String[] parts = new String[1+classRefs.length];
             parts[0] = formRef.stringValue();
-            for (int i = 1; i < parts.length; i++)
-                parts[i] = classRefs[i-1].stringValue();
+            for (int i = 1; i < parts.length; i++) {
+                parts[i] = classRefs[i - 1].stringValue();
+            }
             return flattenSignature(parts).intern();
         }
 
@@ -543,19 +542,23 @@
             int size = 0;
             for (int i = min; i < max; i++) {
                 switch (form.charAt(i)) {
-                case 'D':
-                case 'J':
-                    if (countDoublesTwice) size++;
-                    break;
-                case '[':
-                    // Skip rest of array info.
-                    while (form.charAt(i) == '[') ++i;
-                    break;
-                case ';':
-                    continue;
-                default:
-                    assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
-                    break;
+                    case 'D':
+                    case 'J':
+                        if (countDoublesTwice) {
+                            size++;
+                        }
+                        break;
+                    case '[':
+                        // Skip rest of array info.
+                        while (form.charAt(i) == '[') {
+                            ++i;
+                        }
+                        break;
+                    case ';':
+                        continue;
+                    default:
+                        assert (0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
+                        break;
                 }
                 size++;
             }
@@ -586,8 +589,9 @@
                 s = "/" + formRef.stringValue();
             }
             int i;
-            while ((i = s.indexOf(';')) >= 0)
-                s = s.substring(0,i) + s.substring(i+1);
+            while ((i = s.indexOf(';')) >= 0) {
+                s = s.substring(0, i) + s.substring(i + 1);
+            }
             return s;
         }
     }
@@ -732,11 +736,11 @@
             clearIndex();
             this.cpMap = cpMap;
         }
-        protected Index(String debugName, Collection cpMapList) {
+        protected Index(String debugName, Collection<Entry> cpMapList) {
             this(debugName);
             setMap(cpMapList);
         }
-        protected void setMap(Collection cpMapList) {
+        protected void setMap(Collection<Entry> cpMapList) {
             cpMap = new Entry[cpMapList.size()];
             cpMapList.toArray(cpMap);
             setMap(cpMap);
@@ -756,11 +760,13 @@
         //
         // As a special hack, if flattenSigs, signatures are
         // treated as equivalent entries of cpMap.  This is wrong
-        // fron a Collection point of view, because contains()
+        // from a Collection point of view, because contains()
         // reports true for signatures, but the iterator()
         // never produces them!
         private int findIndexOf(Entry e) {
-            if (indexKey == null)  initializeIndex();
+            if (indexKey == null) {
+                initializeIndex();
+            }
             int probe = findIndexLocation(e);
             if (indexKey[probe] != e) {
                 if (flattenSigs && e.tag == CONSTANT_Signature) {
@@ -832,7 +838,9 @@
                 System.out.println("initialize Index "+debugName+" ["+size()+"]");
             int hsize0 = (int)((cpMap.length + 10) * 1.5);
             int hsize = 1;
-            while (hsize < hsize0)  hsize <<= 1;
+            while (hsize < hsize0) {
+                hsize <<= 1;
+            }
             indexKey   = new Entry[hsize];
             indexValue = new int[hsize];
             for (int i = 0; i < cpMap.length; i++) {
@@ -855,7 +863,7 @@
             return toArray(new Entry[size()]);
         }
         public Object clone() {
-            return new Index(debugName, (Entry[]) cpMap.clone());
+            return new Index(debugName, cpMap.clone());
         }
         public String toString() {
             return "Index "+debugName+" ["+size()+"]";
@@ -901,22 +909,24 @@
     public static
     Index[] partition(Index ix, int[] keys) {
         // %%% Should move this into class Index.
-        ArrayList parts = new ArrayList();
+        ArrayList<List<Entry>> parts = new ArrayList<>();
         Entry[] cpMap = ix.cpMap;
         assert(keys.length == cpMap.length);
         for (int i = 0; i < keys.length; i++) {
             int key = keys[i];
             if (key < 0)  continue;
-            while (key >= parts.size())  parts.add(null);
-            ArrayList part = (ArrayList) parts.get(key);
+            while (key >= parts.size()) {
+                parts.add(null);
+            }
+            List<Entry> part = parts.get(key);
             if (part == null) {
-                parts.set(key, part = new ArrayList());
+                parts.set(key, part = new ArrayList<>());
             }
             part.add(cpMap[i]);
         }
         Index[] indexes = new Index[parts.size()];
         for (int key = 0; key < indexes.length; key++) {
-            ArrayList part = (ArrayList) parts.get(key);
+            List<Entry> part = parts.get(key);
             if (part == null)  continue;
             indexes[key] = new Index(ix.debugName+"/part#"+key, part);
             assert(indexes[key].indexOf(part.get(0)) == 0);
@@ -1048,9 +1058,10 @@
                     whichClasses[i] = whichClass;
                 }
                 perClassIndexes = partition(allMembers, whichClasses);
-                for (int i = 0; i < perClassIndexes.length; i++)
-                    assert(perClassIndexes[i]==null
-                            || perClassIndexes[i].assertIsSorted());
+                for (int i = 0; i < perClassIndexes.length; i++) {
+                    assert (perClassIndexes[i] == null ||
+                            perClassIndexes[i].assertIsSorted());
+                }
                 indexByTagAndClass[tag] = perClassIndexes;
             }
             int whichClass = allClasses.indexOf(classRef);
@@ -1113,7 +1124,7 @@
      *  Also, discard null from cpRefs.
      */
     public static
-    void completeReferencesIn(Set cpRefs, boolean flattenSigs) {
+    void completeReferencesIn(Set<Entry> cpRefs, boolean flattenSigs) {
         cpRefs.remove(null);
         for (ListIterator work =
                  new ArrayList(cpRefs).listIterator(cpRefs.size());
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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,7 +25,6 @@
 
 package com.sun.java.util.jar.pack;
 
-import java.lang.Error;
 import java.io.*;
 import java.text.MessageFormat;
 import java.util.*;
@@ -35,10 +34,11 @@
 /** Command line interface for Pack200.
  */
 class Driver {
-        private static final ResourceBundle RESOURCE= ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
+        private static final ResourceBundle RESOURCE =
+                ResourceBundle.getBundle("com.sun.java.util.jar.pack.DriverResource");
 
     public static void main(String[] ava) throws IOException {
-        ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
+        ArrayList<String> av = new ArrayList<>(Arrays.asList(ava));
 
         boolean doPack   = true;
         boolean doUnpack = false;
@@ -61,7 +61,7 @@
         }
 
         // Collect engine properties here:
-        HashMap<String,String> engProps = new HashMap<String,String>();
+        HashMap<String,String> engProps = new HashMap<>();
         engProps.put(verboseProp, System.getProperty(verboseProp));
 
         String optionMap;
@@ -75,7 +75,7 @@
         }
 
         // Collect argument properties here:
-        HashMap<String,String> avProps = new HashMap<String,String>();
+        HashMap<String,String> avProps = new HashMap<>();
         try {
             for (;;) {
                 String state = parseCommandOptions(av, optionMap, avProps);
@@ -133,8 +133,9 @@
                     if (engProps.get(verboseProp) != null)
                         fileProps.list(System.out);
                     propIn.close();
-                    for (Map.Entry<Object,Object> me : fileProps.entrySet())
-                        engProps.put((String)me.getKey(), (String)me.getValue());
+                    for (Map.Entry<Object,Object> me : fileProps.entrySet()) {
+                        engProps.put((String) me.getKey(), (String) me.getValue());
+                    }
                 } else if (state == "--version") {
                         System.out.println(MessageFormat.format(RESOURCE.getString(DriverResource.VERSION), Driver.class.getName(), "1.31, 07/05/05"));
                     return;
@@ -493,7 +494,7 @@
         String resultString = null;
 
         // Convert options string into optLines dictionary.
-        TreeMap<String,String[]> optmap = new TreeMap<String,String[]>();
+        TreeMap<String,String[]> optmap = new TreeMap<>();
     loadOptmap:
         for (String optline : options.split("\n")) {
             String[] words = optline.split("\\p{Space}+");
@@ -687,7 +688,9 @@
         // Report number of arguments consumed.
         args.subList(0, argp.nextIndex()).clear();
         // Report any unconsumed partial argument.
-        while (pbp.hasPrevious())  args.add(0, pbp.previous());
+        while (pbp.hasPrevious()) {
+            args.add(0, pbp.previous());
+        }
         //System.out.println(args+" // "+properties+" -> "+resultString);
         return resultString;
     }
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -28,13 +28,8 @@
 
 import java.nio.*;
 import java.io.*;
-import java.nio.channels.*;
-import java.util.Date;
 import java.util.jar.*;
 import java.util.zip.*;
-import java.util.*;
-//import com.sun.java.util.jar.pack.Pack200;
-
 
 class NativeUnpack {
     // Pointer to the native unpacker obj
@@ -91,13 +86,13 @@
     NativeUnpack(UnpackerImpl p200) {
         super();
         _p200  = p200;
-        _props = p200._props;
+        _props = p200.props;
         p200._nunp = this;
     }
 
     // for JNI callbacks
     static private Object currentInstance() {
-        UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get();
+        UnpackerImpl p200 = (UnpackerImpl) Utils.getTLGlobals();
         return (p200 == null)? null: p200._nunp;
     }
 
@@ -216,10 +211,10 @@
                 ++_fileCount;
                 updateProgress();
             }
+            presetInput = getUnusedInput();
             long consumed = finish();
             if (_verbose > 0)
                 Utils.log.info("bytes consumed = "+consumed);
-            presetInput = getUnusedInput();
             if (presetInput == null &&
                 !Utils.isPackMagic(Utils.readMagic(in))) {
                 break;
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java	Thu Sep 02 12:17:21 2010 -0700
@@ -25,9 +25,9 @@
 
 package com.sun.java.util.jar.pack;
 
+import com.sun.java.util.jar.pack.Attribute.Layout;
 import java.lang.reflect.Modifier;
 import java.util.*;
-import java.util.zip.*;
 import java.util.jar.*;
 import java.io.*;
 import com.sun.java.util.jar.pack.ConstantPool.*;
@@ -77,10 +77,11 @@
         cp = new ConstantPool.IndexGroup();
         classes.clear();
         files.clear();
+        BandStructure.nextSeqForDebug = 0;
     }
 
     int getPackageVersion() {
-        return (package_majver << 16) + (int)package_minver;
+        return (package_majver << 16) + package_minver;
     }
 
     // Special empty versions of Code and InnerClasses, used for markers.
@@ -89,7 +90,7 @@
     public static final Attribute.Layout attrSourceFileSpecial;
     public static final Map attrDefs;
     static {
-        HashMap ad = new HashMap(2);
+        HashMap<Layout, Attribute> ad = new HashMap<>(3);
         attrCodeEmpty = Attribute.define(ad, ATTR_CONTEXT_METHOD,
                                          "Code", "").layout();
         attrInnerClassesEmpty = Attribute.define(ad, ATTR_CONTEXT_CLASS,
@@ -159,9 +160,9 @@
         }
     }
 
-    ArrayList classes = new ArrayList();
+    ArrayList<Package.Class> classes = new ArrayList<>();
 
-    public List getClasses() {
+    public List<Package.Class> getClasses() {
         return classes;
     }
 
@@ -186,11 +187,11 @@
         ClassEntry[] interfaces;
 
         // Class parts
-        ArrayList fields;
-        ArrayList methods;
+        ArrayList<Field> fields;
+        ArrayList<Method> methods;
         //ArrayList attributes;  // in Attribute.Holder.this.attributes
         // Note that InnerClasses may be collected at the package level.
-        ArrayList innerClasses;
+        ArrayList<InnerClass> innerClasses;
 
         Class(int flags, ClassEntry thisClass, ClassEntry superClass, ClassEntry[] interfaces) {
             this.magic      = JAVA_MAGIC;
@@ -270,7 +271,7 @@
             if (a != olda) {
                 if (verbose > 2)
                     Utils.log.fine("recoding obvious SourceFile="+obvious);
-                List newAttrs = new ArrayList(getAttributes());
+                List<Attribute> newAttrs = new ArrayList<>(getAttributes());
                 int where = newAttrs.indexOf(olda);
                 newAttrs.set(where, a);
                 setAttributes(newAttrs);
@@ -295,12 +296,12 @@
         boolean hasInnerClasses() {
             return innerClasses != null;
         }
-        List getInnerClasses() {
+        List<InnerClass> getInnerClasses() {
             return innerClasses;
         }
 
-        public void setInnerClasses(Collection ics) {
-            innerClasses = (ics == null) ? null : new ArrayList(ics);
+        public void setInnerClasses(Collection<InnerClass> ics) {
+            innerClasses = (ics == null) ? null : new ArrayList<InnerClass>(ics);
             // Edit the attribute list, if necessary.
             Attribute a = getAttribute(attrInnerClassesEmpty);
             if (innerClasses != null && a == null)
@@ -318,19 +319,18 @@
          *  The order of the resulting list is consistent
          *  with that of Package.this.allInnerClasses.
          */
-        public List computeGloballyImpliedICs() {
-            HashSet cpRefs = new HashSet();
+        public List<InnerClass> computeGloballyImpliedICs() {
+            HashSet<Entry> cpRefs = new HashSet<>();
             {   // This block temporarily displaces this.innerClasses.
-                ArrayList innerClassesSaved = innerClasses;
+                ArrayList<InnerClass> innerClassesSaved = innerClasses;
                 innerClasses = null;  // ignore for the moment
                 visitRefs(VRM_CLASSIC, cpRefs);
                 innerClasses = innerClassesSaved;
             }
             ConstantPool.completeReferencesIn(cpRefs, true);
 
-            HashSet icRefs = new HashSet();
-            for (Iterator i = cpRefs.iterator(); i.hasNext(); ) {
-                Entry e = (Entry) i.next();
+            HashSet<Entry> icRefs = new HashSet<>();
+            for (Entry e : cpRefs) {
                 // Restrict cpRefs to InnerClasses entries only.
                 if (!(e instanceof ClassEntry))  continue;
                 // For every IC reference, add its outers also.
@@ -345,9 +345,8 @@
             // This loop is structured this way so as to accumulate
             // entries into impliedICs in an order which reflects
             // the order of allInnerClasses.
-            ArrayList impliedICs = new ArrayList();
-            for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
-                InnerClass ic = (InnerClass) i.next();
+            ArrayList<InnerClass> impliedICs = new ArrayList<>();
+            for (InnerClass ic : allInnerClasses) {
                 // This one is locally relevant if it describes
                 // a member of the current class, or if the current
                 // class uses it somehow.  In the particular case
@@ -366,10 +365,11 @@
 
         // Helper for both minimizing and expanding.
         // Computes a symmetric difference.
-        private List computeICdiff() {
-            List impliedICs = computeGloballyImpliedICs();
-            List actualICs  = getInnerClasses();
-            if (actualICs == null)  actualICs = Collections.EMPTY_LIST;
+        private List<InnerClass> computeICdiff() {
+            List<InnerClass> impliedICs = computeGloballyImpliedICs();
+            List<InnerClass> actualICs  = getInnerClasses();
+            if (actualICs == null)
+                actualICs = Collections.EMPTY_LIST;
 
             // Symmetric difference is calculated from I, A like this:
             //  diff = (I+A) - (I*A)
@@ -388,8 +388,8 @@
                 // Diff is A since I is empty.
             }
             // (I*A) is non-trivial
-            HashSet center = new HashSet(actualICs);
-            center.retainAll(new HashSet(impliedICs));
+            HashSet<InnerClass> center = new HashSet<>(actualICs);
+            center.retainAll(new HashSet<>(impliedICs));
             impliedICs.addAll(actualICs);
             impliedICs.removeAll(center);
             // Diff is now I^A = (I+A)-(I*A).
@@ -407,9 +407,9 @@
          *  to use the globally implied ICs changed.
          */
         void minimizeLocalICs() {
-            List diff = computeICdiff();
-            List actualICs = innerClasses;
-            List localICs;  // will be the diff, modulo edge cases
+            List<InnerClass> diff = computeICdiff();
+            List<InnerClass> actualICs = innerClasses;
+            List<InnerClass> localICs;  // will be the diff, modulo edge cases
             if (diff.isEmpty()) {
                 // No diff, so transmit no attribute.
                 localICs = null;
@@ -439,12 +439,12 @@
          *  Otherwise, return positive if any IC tuples were added.
          */
         int expandLocalICs() {
-            List localICs = innerClasses;
-            List actualICs;
+            List<InnerClass> localICs = innerClasses;
+            List<InnerClass> actualICs;
             int changed;
             if (localICs == null) {
                 // Diff was empty.  (Common case.)
-                List impliedICs = computeGloballyImpliedICs();
+                List<InnerClass> impliedICs = computeGloballyImpliedICs();
                 if (impliedICs.isEmpty()) {
                     actualICs = null;
                     changed = 0;
@@ -490,7 +490,7 @@
             protected Entry[] getCPMap() {
                 return cpMap;
             }
-            protected void visitRefs(int mode, Collection refs) {
+            protected void visitRefs(int mode, Collection<Entry> refs) {
                 if (verbose > 2)  Utils.log.fine("visitRefs "+this);
                 // Careful:  The descriptor is used by the package,
                 // but the classfile breaks it into component refs.
@@ -518,7 +518,7 @@
                 super(flags, descriptor);
                 assert(!descriptor.isMethod());
                 if (fields == null)
-                    fields = new ArrayList();
+                    fields = new ArrayList<>();
                 boolean added = fields.add(this);
                 assert(added);
                 order = fields.size();
@@ -543,7 +543,7 @@
                 super(flags, descriptor);
                 assert(descriptor.isMethod());
                 if (methods == null)
-                    methods = new ArrayList();
+                    methods = new ArrayList<>();
                 boolean added = methods.add(this);
                 assert(added);
             }
@@ -573,7 +573,7 @@
                     code.strip(attrName);
                 super.strip(attrName);
             }
-            protected void visitRefs(int mode, Collection refs) {
+            protected void visitRefs(int mode, Collection<Entry> refs) {
                 super.visitRefs(mode, refs);
                 if (code != null) {
                     if (mode == VRM_CLASSIC) {
@@ -614,7 +614,7 @@
             super.strip(attrName);
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             if (verbose > 2)  Utils.log.fine("visitRefs "+this);
             refs.add(thisClass);
             refs.add(superClass);
@@ -641,7 +641,7 @@
             super.visitRefs(mode, refs);
         }
 
-        protected void visitInnerClassRefs(int mode, Collection refs) {
+        protected void visitInnerClassRefs(int mode, Collection<Entry> refs) {
             Package.visitInnerClassRefs(innerClasses, mode, refs);
         }
 
@@ -713,16 +713,15 @@
     }
 
     // What non-class files are in this unit?
-    ArrayList files = new ArrayList();
+    ArrayList<File> files = new ArrayList<>();
 
-    public List getFiles() {
+    public List<File> getFiles() {
         return files;
     }
 
-    public List getClassStubs() {
-        ArrayList classStubs = new ArrayList(classes.size());
-        for (Iterator i = classes.iterator(); i.hasNext(); ) {
-            Class cls = (Class) i.next();
+    public List<File> getClassStubs() {
+        ArrayList<File> classStubs = new ArrayList<>(classes.size());
+        for (Class cls : classes) {
             assert(cls.file.isClassStub());
             classStubs.add(cls.file);
         }
@@ -840,7 +839,7 @@
         public InputStream getInputStream() {
             InputStream in = new ByteArrayInputStream(append.toByteArray());
             if (prepend.size() == 0)  return in;
-            ArrayList isa = new ArrayList(prepend.size()+1);
+            ArrayList<InputStream> isa = new ArrayList<>(prepend.size()+1);
             for (Iterator i = prepend.iterator(); i.hasNext(); ) {
                 byte[] bytes = (byte[]) i.next();
                 isa.add(new ByteArrayInputStream(bytes));
@@ -849,7 +848,7 @@
             return new SequenceInputStream(Collections.enumeration(isa));
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             assert(name != null);
             refs.add(name);
         }
@@ -877,8 +876,8 @@
     }
 
     // Is there a globally declared table of inner classes?
-    ArrayList allInnerClasses = new ArrayList();
-    HashMap   allInnerClassesByThis;
+    ArrayList<InnerClass> allInnerClasses = new ArrayList<>();
+    HashMap<ClassEntry, InnerClass>   allInnerClassesByThis;
 
     public
     List getAllInnerClasses() {
@@ -886,15 +885,14 @@
     }
 
     public
-    void setAllInnerClasses(Collection ics) {
+    void setAllInnerClasses(Collection<InnerClass> ics) {
         assert(ics != allInnerClasses);
         allInnerClasses.clear();
         allInnerClasses.addAll(ics);
 
         // Make an index:
-        allInnerClassesByThis = new HashMap(allInnerClasses.size());
-        for (Iterator i = allInnerClasses.iterator(); i.hasNext(); ) {
-            InnerClass ic = (InnerClass) i.next();
+        allInnerClassesByThis = new HashMap<>(allInnerClasses.size());
+        for (InnerClass ic : allInnerClasses) {
             Object pic = allInnerClassesByThis.put(ic.thisClass, ic);
             assert(pic == null);  // caller must ensure key uniqueness!
         }
@@ -904,7 +902,7 @@
     public
     InnerClass getGlobalInnerClass(Entry thisClass) {
         assert(thisClass instanceof ClassEntry);
-        return (InnerClass) allInnerClassesByThis.get(thisClass);
+        return allInnerClassesByThis.get(thisClass);
     }
 
     static
@@ -963,7 +961,7 @@
             return this.thisClass.compareTo(that.thisClass);
         }
 
-        protected void visitRefs(int mode, Collection refs) {
+        protected void visitRefs(int mode, Collection<Entry> refs) {
             refs.add(thisClass);
             if (mode == VRM_CLASSIC || !predictable) {
                 // If the name can be demangled, the package omits
@@ -980,7 +978,7 @@
 
     // Helper for building InnerClasses attributes.
     static private
-    void visitInnerClassRefs(Collection innerClasses, int mode, Collection refs) {
+    void visitInnerClassRefs(Collection innerClasses, int mode, Collection<Entry> refs) {
         if (innerClasses == null) {
             return;  // no attribute; nothing to do
         }
@@ -1165,9 +1163,8 @@
         }
     }
 
-    protected void visitRefs(int mode, Collection refs) {
-        for (Iterator i = classes.iterator(); i.hasNext(); ) {
-            Class c = (Class)i.next();
+    protected void visitRefs(int mode, Collection<Entry> refs) {
+        for ( Class c : classes) {
             c.visitRefs(mode, refs);
         }
         if (mode != VRM_CLASSIC) {
@@ -1259,7 +1256,7 @@
     }
 
     // Use this before writing the package file.
-    void buildGlobalConstantPool(Set requiredEntries) {
+    void buildGlobalConstantPool(Set<Entry> requiredEntries) {
         if (verbose > 1)
             Utils.log.fine("Checking for unused CP entries");
         requiredEntries.add(getRefString(""));  // uconditionally present
@@ -1291,9 +1288,8 @@
 
     // Use this before writing the class files.
     void ensureAllClassFiles() {
-        HashSet fileSet = new HashSet(files);
-        for (Iterator i = classes.iterator(); i.hasNext(); ) {
-            Class cls = (Class) i.next();
+        HashSet<File> fileSet = new HashSet<>(files);
+        for (Class cls : classes) {
             // Add to the end of ths list:
             if (!fileSet.contains(cls.file))
                 files.add(cls.file);
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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,12 +25,11 @@
 
 package com.sun.java.util.jar.pack;
 
+import com.sun.java.util.jar.pack.Attribute.Layout;
 import java.util.*;
 import java.util.jar.*;
-import java.util.zip.*;
 import java.io.*;
 import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
 
 
 /*
@@ -41,31 +40,22 @@
  */
 
 
-public class PackerImpl implements Pack200.Packer {
+public class PackerImpl  extends TLGlobals implements Pack200.Packer {
 
     /**
      * Constructs a Packer object and sets the initial state of
      * the packer engines.
      */
-    public PackerImpl() {
-        _props = new PropMap();
-        //_props.getProperty() consults defaultProps invisibly.
-        //_props.putAll(defaultProps);
-    }
-
-
-    // Private stuff.
-    final PropMap _props;
+    public PackerImpl() {}
 
     /**
      * Get the set of options for the pack and unpack engines.
      * @return A sorted association of option key strings to option values.
      */
-    public SortedMap properties() {
-        return _props;
+    public SortedMap<String, String> properties() {
+        return props;
     }
 
-
     //Driver routines
 
     /**
@@ -78,21 +68,22 @@
      */
     public void pack(JarFile in, OutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
-        TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
-            TimeZone.getDefault();
+        TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
+                      ? null
+                      : TimeZone.getDefault();
         try {
             Utils.currentInstance.set(this);
             if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
 
-            if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
+            if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
                 Utils.copyJarFile(in, out);
             } else {
                 (new DoPack()).run(in, out);
-                in.close();
             }
         } finally {
             Utils.currentInstance.set(null);
             if (tz != null) TimeZone.setDefault(tz);
+            in.close();
         }
     }
 
@@ -112,21 +103,20 @@
      */
     public void pack(JarInputStream in, OutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
-        TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
+        TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
             TimeZone.getDefault();
         try {
             Utils.currentInstance.set(this);
             if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-            if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
+            if ("0".equals(props.getProperty(Pack200.Packer.EFFORT))) {
                 Utils.copyJarFile(in, out);
             } else {
                 (new DoPack()).run(in, out);
-                in.close();
             }
         } finally {
             Utils.currentInstance.set(null);
             if (tz != null) TimeZone.setDefault(tz);
-
+            in.close();
         }
     }
     /**
@@ -134,7 +124,7 @@
      * @param listener  An object to be invoked when a property is changed.
      */
     public void addPropertyChangeListener(PropertyChangeListener listener) {
-        _props.addListener(listener);
+        props.addListener(listener);
     }
 
     /**
@@ -142,7 +132,7 @@
      * @param listener  The PropertyChange listener to be removed.
      */
     public void removePropertyChangeListener(PropertyChangeListener listener) {
-        _props.removeListener(listener);
+        props.removeListener(listener);
     }
 
 
@@ -151,11 +141,11 @@
 
     // The packer worker.
     private class DoPack {
-        final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+        final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
 
         {
-            _props.setInteger(Pack200.Packer.PROGRESS, 0);
-            if (verbose > 0) Utils.log.info(_props.toString());
+            props.setInteger(Pack200.Packer.PROGRESS, 0);
+            if (verbose > 0) Utils.log.info(props.toString());
         }
 
         // Here's where the bits are collected before getting packed:
@@ -163,7 +153,7 @@
 
         final String unknownAttrCommand;
         {
-            String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
+            String uaMode = props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
             if (!(Pack200.Packer.STRIP.equals(uaMode) ||
                   Pack200.Packer.PASS.equals(uaMode) ||
                   Pack200.Packer.ERROR.equals(uaMode))) {
@@ -191,13 +181,12 @@
             };
             for (int i = 0; i < ctypes.length; i++) {
                 String pfx = keys[i];
-                Map map = _props.prefixMap(pfx);
-                for (Iterator j = map.keySet().iterator(); j.hasNext(); ) {
-                    String key = (String) j.next();
+                Map<String, String> map = props.prefixMap(pfx);
+                for (String key : map.keySet()) {
                     assert(key.startsWith(pfx));
                     String name = key.substring(pfx.length());
-                    String layout = _props.getProperty(key);
-                    Object lkey = Attribute.keyForLookup(ctypes[i], name);
+                    String layout = props.getProperty(key);
+                    Layout lkey = Attribute.keyForLookup(ctypes[i], name);
                     if (Pack200.Packer.STRIP.equals(layout) ||
                         Pack200.Packer.PASS.equals(layout) ||
                         Pack200.Packer.ERROR.equals(layout)) {
@@ -222,25 +211,25 @@
         }
 
         final boolean keepFileOrder
-            = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
+            = props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
         final boolean keepClassOrder
-            = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
+            = props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
 
         final boolean keepModtime
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
+            = Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
         final boolean latestModtime
-            = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
+            = Pack200.Packer.LATEST.equals(props.getProperty(Pack200.Packer.MODIFICATION_TIME));
         final boolean keepDeflateHint
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT));
+            = Pack200.Packer.KEEP.equals(props.getProperty(Pack200.Packer.DEFLATE_HINT));
         {
             if (!keepModtime && !latestModtime) {
-                int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME);
+                int modtime = props.getTime(Pack200.Packer.MODIFICATION_TIME);
                 if (modtime != Constants.NO_MODTIME) {
                     pkg.default_modtime = modtime;
                 }
             }
             if (!keepDeflateHint) {
-                boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT);
+                boolean deflate_hint = props.getBoolean(Pack200.Packer.DEFLATE_HINT);
                 if (deflate_hint) {
                     pkg.default_options |= Constants.AO_DEFLATE_HINT;
                 }
@@ -254,10 +243,10 @@
         final long segmentLimit;
         {
             long limit;
-            if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
+            if (props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
                 limit = -1;
             else
-                limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT);
+                limit = props.getLong(Pack200.Packer.SEGMENT_LIMIT);
             limit = Math.min(Integer.MAX_VALUE, limit);
             limit = Math.max(-1, limit);
             if (limit == -1)
@@ -265,10 +254,10 @@
             segmentLimit = limit;
         }
 
-        final List passFiles;  // parsed pack.pass.file options
+        final List<String> passFiles;  // parsed pack.pass.file options
         {
             // Which class files will be passed through?
-            passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX);
+            passFiles = props.getProperties(Pack200.Packer.PASS_FILE_PFX);
             for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) {
                 String file = (String) i.next();
                 if (file == null) { i.remove(); continue; }
@@ -283,28 +272,28 @@
         {
             // Fill in permitted range of major/minor version numbers.
             int ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
                 pkg.min_class_majver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
                 pkg.min_class_minver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
                 pkg.max_class_majver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
                 pkg.max_class_minver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
                 pkg.package_minver = (short) ver;
-            if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
+            if ((ver = props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
                 pkg.package_majver = (short) ver;
         }
 
         {
             // Hook for testing:  Forces use of special archive modes.
-            int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options");
+            int opt = props.getInteger(Utils.COM_PREFIX+"archive.options");
             if (opt != 0)
                 pkg.default_options |= opt;
         }
 
-        // (Done collecting options from _props.)
+        // (Done collecting options from props.)
 
         boolean isClassFile(String name) {
             if (!name.endsWith(".class"))  return false;
@@ -423,16 +412,18 @@
                 Package.File file = null;
                 // (5078608) : discount the resource files in META-INF
                 // from segment computation.
-                long inflen = (isMetaInfFile(name)) ?  0L :
-                                inFile.getInputLength();
+                long inflen = (isMetaInfFile(name))
+                              ? 0L
+                              : inFile.getInputLength();
 
                 if ((segmentSize += inflen) > segmentLimit) {
                     segmentSize -= inflen;
                     int nextCount = -1;  // don't know; it's a stream
                     flushPartial(out, nextCount);
                 }
-                if (verbose > 1)
+                if (verbose > 1) {
                     Utils.log.fine("Reading " + name);
+                }
 
                 assert(je.isDirectory() == name.endsWith("/"));
 
@@ -450,18 +441,18 @@
         }
 
         void run(JarFile in, OutputStream out) throws IOException {
-            List inFiles = scanJar(in);
+            List<InFile> inFiles = scanJar(in);
 
             if (verbose > 0)
                 Utils.log.info("Reading " + inFiles.size() + " files...");
 
             int numDone = 0;
-            for (Iterator i = inFiles.iterator(); i.hasNext(); ) {
-                InFile inFile = (InFile) i.next();
+            for (InFile inFile : inFiles) {
                 String name      = inFile.name;
                 // (5078608) : discount the resource files completely from segmenting
-                long inflen = (isMetaInfFile(name)) ? 0L :
-                                inFile.getInputLength() ;
+                long inflen = (isMetaInfFile(name))
+                               ? 0L
+                               : inFile.getInputLength() ;
                 if ((segmentSize += inflen) > segmentLimit) {
                     segmentSize -= inflen;
                     // Estimate number of remaining segments:
@@ -530,11 +521,11 @@
         }
 
         void flushPartial(OutputStream out, int nextCount) throws IOException {
-            if (pkg.files.size() == 0 && pkg.classes.size() == 0) {
+            if (pkg.files.isEmpty() && pkg.classes.isEmpty()) {
                 return;  // do not flush an empty segment
             }
             flushPackage(out, Math.max(1, nextCount));
-            _props.setInteger(Pack200.Packer.PROGRESS, 25);
+            props.setInteger(Pack200.Packer.PROGRESS, 25);
             // In case there will be another segment:
             makeNextPackage();
             segmentCount += 1;
@@ -543,10 +534,10 @@
         }
 
         void flushAll(OutputStream out) throws IOException {
-            _props.setInteger(Pack200.Packer.PROGRESS, 50);
+            props.setInteger(Pack200.Packer.PROGRESS, 50);
             flushPackage(out, 0);
             out.flush();
-            _props.setInteger(Pack200.Packer.PROGRESS, 100);
+            props.setInteger(Pack200.Packer.PROGRESS, 100);
             segmentCount += 1;
             segmentTotalSize += segmentSize;
             segmentSize = 0;
@@ -582,11 +573,11 @@
             pkg.trimStubs();
 
             // Do some stripping, maybe.
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug"))        pkg.stripAttributeKind("Debug");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile"))      pkg.stripAttributeKind("Compile");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants"))    pkg.stripAttributeKind("Constant");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions"))   pkg.stripAttributeKind("Exceptions");
-            if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.debug"))        pkg.stripAttributeKind("Debug");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.compile"))      pkg.stripAttributeKind("Compile");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.constants"))    pkg.stripAttributeKind("Constant");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.exceptions"))   pkg.stripAttributeKind("Exceptions");
+            if (props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
 
             // Must choose an archive version; PackageWriter does not.
             if (pkg.package_majver <= 0)  pkg.choosePackageVersion();
@@ -606,11 +597,10 @@
             }
         }
 
-        List scanJar(JarFile jf) throws IOException {
+        List<InFile> scanJar(JarFile jf) throws IOException {
             // Collect jar entries, preserving order.
-            List inFiles = new ArrayList();
-            for (Enumeration e = jf.entries(); e.hasMoreElements(); ) {
-                JarEntry je = (JarEntry) e.nextElement();
+            List<InFile> inFiles = new ArrayList<>();
+            for (JarEntry je : Collections.list(jf.entries())) {
                 InFile inFile = new InFile(jf, je);
                 assert(je.isDirectory() == inFile.name.endsWith("/"));
                 inFiles.add(inFile);
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java	Thu Sep 02 12:17:21 2010 -0700
@@ -91,7 +91,7 @@
                   String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)));
 
         // The segment size is unlimited
-        props.put(Pack200.Packer.SEGMENT_LIMIT, "");
+        props.put(Pack200.Packer.SEGMENT_LIMIT, "-1");
 
         // Preserve file ordering by default.
         props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/TLGlobals.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package com.sun.java.util.jar.pack;
+
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
+import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
+import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedMap;
+
+/*
+ * @author ksrini
+ */
+
+/*
+ * This class provides a container to hold the global variables, for packer
+ * and unpacker instances. This is typically stashed away in a ThreadLocal,
+ * and the storage is destroyed upon completion. Therefore any local
+ * references to these members must be eliminated appropriately to prevent a
+ * memory leak.
+ */
+class TLGlobals {
+    // Global environment
+    final PropMap props;
+
+    // Needed by ConstantPool.java
+    private final Map<String, Utf8Entry> utf8Entries;
+    private final Map<String, ClassEntry> classEntries;
+    private final Map<Object, LiteralEntry> literalEntries;
+    private final Map<String, SignatureEntry> signatureEntries;
+    private final Map<String, DescriptorEntry> descriptorEntries;
+    private final Map<String, MemberEntry> memberEntries;
+
+    TLGlobals() {
+        utf8Entries = new HashMap<>();
+        classEntries = new HashMap<>();
+        literalEntries = new HashMap<>();
+        signatureEntries = new HashMap<>();
+        descriptorEntries = new HashMap<>();
+        memberEntries = new HashMap<>();
+        props = new PropMap();
+    }
+
+    SortedMap<Object, Object> getPropMap() {
+        return props;
+    }
+
+    Map<String, Utf8Entry> getUtf8Entries() {
+        return utf8Entries;
+    }
+
+    Map<String, ClassEntry> getClassEntries() {
+        return classEntries;
+    }
+
+    Map<Object, LiteralEntry> getLiteralEntries() {
+        return literalEntries;
+    }
+
+    Map<String, DescriptorEntry> getDescriptorEntries() {
+         return descriptorEntries;
+    }
+
+    Map<String, SignatureEntry> getSignatureEntries() {
+        return signatureEntries;
+    }
+
+    Map<String, MemberEntry> getMemberEntries() {
+        return memberEntries;
+    }
+}
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -30,7 +30,6 @@
 import java.util.zip.*;
 import java.io.*;
 import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
 
 /*
  * Implementation of the Pack provider.
@@ -40,7 +39,7 @@
  */
 
 
-public class UnpackerImpl implements Pack200.Unpacker {
+public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
 
 
     /**
@@ -48,7 +47,7 @@
      * @param listener  An object to be invoked when a property is changed.
      */
     public void addPropertyChangeListener(PropertyChangeListener listener) {
-        _props.addListener(listener);
+        props.addListener(listener);
     }
 
 
@@ -57,25 +56,19 @@
      * @param listener  The PropertyChange listener to be removed.
      */
     public void removePropertyChangeListener(PropertyChangeListener listener) {
-        _props.removeListener(listener);
+        props.removeListener(listener);
     }
 
-    public UnpackerImpl() {
-        _props = new PropMap();
-        //_props.getProperty() consults defaultProps invisibly.
-        //_props.putAll(defaultProps);
-    }
+    public UnpackerImpl() {}
 
-    // Private stuff.
-    final PropMap _props;
 
 
     /**
      * Get the set of options for the pack and unpack engines.
      * @return A sorted association of option key strings to option values.
      */
-    public SortedMap properties() {
-        return _props;
+    public SortedMap<String, String> properties() {
+        return props;
     }
 
     // Back-pointer to NativeUnpacker, when active.
@@ -101,19 +94,20 @@
      */
     public void unpack(InputStream in0, JarOutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
-        TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
-            TimeZone.getDefault();
+        TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
+                      ? null
+                      : TimeZone.getDefault();
 
         try {
             Utils.currentInstance.set(this);
             if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-            final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+            final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
             BufferedInputStream in = new BufferedInputStream(in0);
             if (Utils.isJarMagic(Utils.readMagic(in))) {
                 if (verbose > 0)
                     Utils.log.info("Copying unpacked JAR file...");
                 Utils.copyJarFile(new JarInputStream(in), out);
-            } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
+            } else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
                 (new DoUnpack()).run(in, out);
                 in.close();
                 Utils.markJarFile(out);
@@ -142,36 +136,38 @@
         // %%% Reconsider if native unpacker learns to memory-map the file.
         FileInputStream instr = new FileInputStream(in);
         unpack(instr, out);
-        if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
+        if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
             in.delete();
         }
     }
 
     private class DoUnpack {
-        final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+        final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
 
         {
-            _props.setInteger(Pack200.Unpacker.PROGRESS, 0);
+            props.setInteger(Pack200.Unpacker.PROGRESS, 0);
         }
 
         // Here's where the bits are read from disk:
         final Package pkg = new Package();
 
         final boolean keepModtime
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
+            = Pack200.Packer.KEEP.equals(
+              props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
         final boolean keepDeflateHint
-            = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
+            = Pack200.Packer.KEEP.equals(
+              props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
         final int modtime;
         final boolean deflateHint;
         {
             if (!keepModtime) {
-                modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
+                modtime = props.getTime(Utils.UNPACK_MODIFICATION_TIME);
             } else {
                 modtime = pkg.default_modtime;
             }
 
             deflateHint = (keepDeflateHint) ? false :
-                _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
+                props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
         }
 
         // Checksum apparatus.
@@ -181,7 +177,7 @@
 
         public void run(BufferedInputStream in, JarOutputStream out) throws IOException {
             if (verbose > 0) {
-                _props.list(System.out);
+                props.list(System.out);
             }
             for (int seg = 1; ; seg++) {
                 unpackSegment(in, out);
@@ -194,25 +190,26 @@
         }
 
         private void unpackSegment(InputStream in, JarOutputStream out) throws IOException {
-            _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
+            props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
             // Process the output directory or jar output.
             new PackageReader(pkg, in).read();
 
-            if (_props.getBoolean("unpack.strip.debug"))    pkg.stripAttributeKind("Debug");
-            if (_props.getBoolean("unpack.strip.compile"))  pkg.stripAttributeKind("Compile");
-            _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
+            if (props.getBoolean("unpack.strip.debug"))    pkg.stripAttributeKind("Debug");
+            if (props.getBoolean("unpack.strip.compile"))  pkg.stripAttributeKind("Compile");
+            props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
             pkg.ensureAllClassFiles();
             // Now write out the files.
-            HashSet classesToWrite = new HashSet(pkg.getClasses());
+            HashSet<Package.Class> classesToWrite = new HashSet<>(pkg.getClasses());
             for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) {
                 Package.File file = (Package.File) i.next();
                 String name = file.nameString;
                 JarEntry je = new JarEntry(Utils.getJarEntryName(name));
                 boolean deflate;
 
-                deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
-                                                   ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) :
-                    deflateHint;
+                deflate = (keepDeflateHint)
+                          ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
+                            ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0))
+                          : deflateHint;
 
                 boolean needCRC = !deflate;  // STORE mode requires CRC
 
@@ -250,7 +247,7 @@
                     Utils.log.info("Writing "+Utils.zeString((ZipEntry)je));
             }
             assert(classesToWrite.isEmpty());
-            _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
+            props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
             pkg.reset();  // reset for the next segment, if any
         }
     }
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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,6 +25,13 @@
 
 package com.sun.java.util.jar.pack;
 
+import com.sun.java.util.jar.pack.Attribute.Layout;
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
+import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
+import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
 import java.util.*;
 import java.util.jar.*;
 import java.util.zip.*;
@@ -113,17 +120,46 @@
      */
     static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200";
 
-   // Keep a TLS point to the current Packer or Unpacker.
-   // This makes it simpler to supply environmental options
+    // Keep a TLS point to the global data and environment.
+    // This makes it simpler to supply environmental options
     // to the engine code, especially the native code.
-    static final ThreadLocal currentInstance = new ThreadLocal();
+    static final ThreadLocal<TLGlobals> currentInstance = new ThreadLocal<>();
+
+    // convenience methods to access the TL globals
+    static TLGlobals getTLGlobals() {
+        return currentInstance.get();
+    }
+
+    static Map<String, Utf8Entry> getUtf8Entries() {
+        return getTLGlobals().getUtf8Entries();
+    }
+
+    static Map<String, ClassEntry> getClassEntries() {
+        return getTLGlobals().getClassEntries();
+    }
+
+    static Map<Object, LiteralEntry> getLiteralEntries() {
+        return getTLGlobals().getLiteralEntries();
+    }
+
+    static Map<String, DescriptorEntry> getDescriptorEntries() {
+         return getTLGlobals().getDescriptorEntries();
+    }
+
+    static Map<String, SignatureEntry> getSignatureEntries() {
+        return getTLGlobals().getSignatureEntries();
+    }
+
+    static Map<String, MemberEntry> getMemberEntries() {
+        return getTLGlobals().getMemberEntries();
+    }
 
     static PropMap currentPropMap() {
         Object obj = currentInstance.get();
         if (obj instanceof PackerImpl)
-            return ((PackerImpl)obj)._props;
+            return ((PackerImpl)obj).props;
         if (obj instanceof UnpackerImpl)
-            return ((UnpackerImpl)obj)._props;
+            return ((UnpackerImpl)obj).props;
         return null;
     }
 
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java	Thu Sep 02 12:17:21 2010 -0700
@@ -813,7 +813,8 @@
         try {
             while (true) {
                 try {
-                    inbuf = new byte[10];
+                    // type and length (at most 128 octets for long form)
+                    inbuf = new byte[129];
 
                     offset = 0;
                     seqlen = 0;
--- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTYResources.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTYResources.java	Thu Sep 02 12:17:21 2010 -0700
@@ -45,7 +45,7 @@
      * @return the contents of this <code>ResourceBundle</code>.
      */
     public Object[][] getContents() {
-        return new Object[][] {
+        Object[][] temp = new Object[][] {
         // NOTE: The value strings in this file containing "{0}" are
         //       processed by the java.text.MessageFormat class.  Any
         //       single quotes appearing in these strings need to be
@@ -449,5 +449,7 @@
              "For command help type ''help'' at {0} prompt"},
         // END OF MATERIAL TO LOCALIZE
         };
+
+        return temp;
     }
 }
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java	Thu Sep 02 12:17:21 2010 -0700
@@ -470,7 +470,7 @@
     public AbstractStringBuilder append(CharSequence s, int start, int end) {
         if (s == null)
             s = "null";
-        if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
+        if ((start < 0) || (start > end) || (end > s.length()))
             throw new IndexOutOfBoundsException(
                 "start " + start + ", end " + end + ", s.length() "
                 + s.length());
@@ -529,7 +529,8 @@
      *         or {@code offset+len > str.length}
      */
     public AbstractStringBuilder append(char str[], int offset, int len) {
-        ensureCapacityInternal(count + len);
+        if (len > 0)                // let arraycopy report AIOOBE for len < 0
+            ensureCapacityInternal(count + len);
         System.arraycopy(str, offset, value, count, len);
         count += len;
         return this;
--- a/jdk/src/share/classes/java/lang/Thread.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/java/lang/Thread.java	Thu Sep 02 12:17:21 2010 -0700
@@ -414,6 +414,18 @@
     }
 
     /**
+     * Throws CloneNotSupportedException as a Thread can not be meaningfully
+     * cloned. Construct a new Thread instead.
+     *
+     * @throws  CloneNotSupportedException
+     *          always
+     */
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+    /**
      * Allocates a new {@code Thread} object. This constructor has the same
      * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
      * {@code (null, null, gname)}, where {@code gname} is a newly generated
--- a/jdk/src/share/classes/java/lang/Throwable.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/java/lang/Throwable.java	Thu Sep 02 12:17:21 2010 -0700
@@ -200,7 +200,16 @@
      * @serial
      * @since 1.7
      */
-    private List<Throwable> suppressedExceptions = Collections.emptyList();
+    private List<Throwable> suppressedExceptions = null;
+    /*
+     * This field is lazily initialized when the first suppressed
+     * exception is added.
+     *
+     * OutOfMemoryError is preallocated in the VM for better OOM
+     * diagnosability during VM initialization. Constructor can't
+     * be not invoked. If a new field to be added in the future must
+     * be initialized to non-null, it requires a synchronized VM change.
+     */
 
     /** Message for trying to suppress a null exception. */
     private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
@@ -329,7 +338,7 @@
      *          cause is nonexistent or unknown.
      * @since 1.4
      */
-    public Throwable getCause() {
+    public synchronized Throwable getCause() {
         return (cause==this ? null : cause);
     }
 
@@ -563,7 +572,7 @@
                 s.println("\tat " + traceElement);
 
             // Print suppressed exceptions, if any
-            for (Throwable se : suppressedExceptions)
+            for (Throwable se : getSuppressedExceptions())
                 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
 
             // Print cause, if any
@@ -604,7 +613,7 @@
                 s.println(prefix + "\t... " + framesInCommon + " more");
 
             // Print suppressed exceptions, if any
-            for (Throwable se : suppressedExceptions)
+            for (Throwable se : getSuppressedExceptions())
                 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
                                            prefix +"\t", dejaVu);
 
@@ -747,7 +756,9 @@
             if (defensiveCopy[i] == null)
                 throw new NullPointerException("stackTrace[" + i + "]");
 
-        this.stackTrace = defensiveCopy;
+        synchronized (this) {
+            this.stackTrace = defensiveCopy;
+        }
     }
 
     /**
@@ -772,11 +783,11 @@
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
         s.defaultReadObject();     // read in all fields
-        List<Throwable> suppressed = Collections.emptyList();
+        List<Throwable> suppressed = null;
         if (suppressedExceptions != null &&
             !suppressedExceptions.isEmpty()) { // Copy Throwables to new list
             suppressed = new ArrayList<Throwable>();
-            for(Throwable t : suppressedExceptions) {
+            for (Throwable t : suppressedExceptions) {
                 if (t == null)
                     throw new NullPointerException(NULL_CAUSE_MESSAGE);
                 suppressed.add(t);
@@ -819,7 +830,7 @@
         if (exception == this)
             throw new IllegalArgumentException("Self-suppression not permitted");
 
-        if (suppressedExceptions.size() == 0)
+        if (suppressedExceptions == null)
             suppressedExceptions = new ArrayList<Throwable>();
         suppressedExceptions.add(exception);
     }
@@ -835,7 +846,10 @@
      *         suppressed to deliver this exception.
      * @since 1.7
      */
-    public Throwable[] getSuppressedExceptions() {
-        return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
+    public synchronized Throwable[] getSuppressedExceptions() {
+        if (suppressedExceptions == null)
+            return EMPTY_THROWABLE_ARRAY;
+        else
+            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
     }
 }
--- a/jdk/src/share/classes/java/net/HttpCookie.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/java/net/HttpCookie.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1093,14 +1093,8 @@
         return sb.toString();
     }
 
-    private static SimpleDateFormat[] cDateFormats = null;
-    static {
-            cDateFormats = new SimpleDateFormat[COOKIE_DATE_FORMATS.length];
-            for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
-                cDateFormats[i] = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US);
-                cDateFormats[i].setTimeZone(TimeZone.getTimeZone("GMT"));
-            }
-    }
+    static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
     /*
      * @param dateString        a date string in one of the formats
      *                          defined in Netscape cookie spec
@@ -1109,12 +1103,14 @@
      *                          time and the time specified by dateString
      */
     private long expiryDate2DeltaSeconds(String dateString) {
-        for (SimpleDateFormat df : cDateFormats) {
+        for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
+            SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US);
+            df.setTimeZone(GMT);
             try {
                 Date date = df.parse(dateString);
                 return (date.getTime() - whenCreated) / 1000;
             } catch (Exception e) {
-
+                // Ignore, try the next date format
             }
         }
         return 0;
--- a/jdk/src/share/classes/java/net/URI.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/java/net/URI.java	Thu Sep 02 12:17:21 2010 -0700
@@ -856,9 +856,7 @@
         try {
             return new URI(str);
         } catch (URISyntaxException x) {
-            IllegalArgumentException y = new IllegalArgumentException();
-            y.initCause(x);
-            throw y;
+            throw new IllegalArgumentException(x.getMessage(), x);
         }
     }
 
--- a/jdk/src/share/classes/java/security/KeyStore.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/java/security/KeyStore.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -131,17 +131,19 @@
  * to read existing entries from the keystore, or to write new entries
  * into the keystore:
  * <pre>
+ *    KeyStore.ProtectionParameter protParam =
+ *        new KeyStore.PasswordProtection(password);
+ *
  *    // get my private key
  *    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
- *        ks.getEntry("privateKeyAlias", password);
+ *        ks.getEntry("privateKeyAlias", protParam);
  *    PrivateKey myPrivateKey = pkEntry.getPrivateKey();
  *
  *    // save my secret key
  *    javax.crypto.SecretKey mySecretKey;
  *    KeyStore.SecretKeyEntry skEntry =
  *        new KeyStore.SecretKeyEntry(mySecretKey);
- *    ks.setEntry("secretKeyAlias", skEntry,
- *        new KeyStore.PasswordProtection(password));
+ *    ks.setEntry("secretKeyAlias", skEntry, protParam);
  *
  *    // store away the keystore
  *    java.io.FileOutputStream fos = null;
--- a/jdk/src/share/classes/java/sql/Date.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/java/sql/Date.java	Thu Sep 02 12:17:21 2010 -0700
@@ -103,27 +103,46 @@
      *         JDBC date escape format (yyyy-mm-dd)
      */
     public static Date valueOf(String s) {
-        int year;
-        int month;
-        int day;
+        final int YEAR_LENGTH = 4;
+        final int MONTH_LENGTH = 2;
+        final int DAY_LENGTH = 2;
+        final int MAX_MONTH = 12;
+        final int MAX_DAY = 31;
         int firstDash;
         int secondDash;
-
-        if (s == null) throw new java.lang.IllegalArgumentException();
+        Date d = null;
 
-        firstDash = s.indexOf('-');
-        secondDash = s.indexOf('-', firstDash+1);
-        if ((firstDash > 0) & (secondDash > 0) & (secondDash < s.length()-1)) {
-            year = Integer.parseInt(s.substring(0, firstDash)) - 1900;
-            month = Integer.parseInt(s.substring(firstDash+1, secondDash)) - 1;
-            day = Integer.parseInt(s.substring(secondDash+1));
-        } else {
+        if (s == null) {
             throw new java.lang.IllegalArgumentException();
         }
 
-        return new Date(year, month, day);
+        firstDash = s.indexOf('-');
+        secondDash = s.indexOf('-', firstDash + 1);
+
+        if ((firstDash > 0) && (secondDash > 0) && (secondDash < s.length() - 1)) {
+            String yyyy = s.substring(0, firstDash);
+            String mm = s.substring(firstDash + 1, secondDash);
+            String dd = s.substring(secondDash + 1);
+            if (yyyy.length() == YEAR_LENGTH && mm.length() == MONTH_LENGTH &&
+                    dd.length() == DAY_LENGTH) {
+                int year = Integer.parseInt(yyyy);
+                int month = Integer.parseInt(mm);
+                int day = Integer.parseInt(dd);
+
+                if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
+                    d = new Date(year - 1900, month - 1, day);
+                }
+            }
+        }
+        if (d == null) {
+            throw new java.lang.IllegalArgumentException();
+        }
+
+        return d;
+
     }
 
+
     /**
      * Formats a date in the date escape format yyyy-mm-dd.
      * <P>
--- a/jdk/src/share/classes/javax/swing/JTable.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/javax/swing/JTable.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -946,7 +946,6 @@
 
     /**
      * Returns the height of a table row, in pixels.
-     * The default row height is 16.0.
      *
      * @return  the height in pixels of a table row
      * @see     #setRowHeight
--- a/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer.java	Thu Sep 02 12:17:21 2010 -0700
@@ -29,7 +29,7 @@
 public class MsgAppletViewer extends ListResourceBundle {
 
     public Object[][] getContents() {
-        return new Object[][] {
+        Object[][] temp = new Object[][] {
             {"textframe.button.dismiss", "Dismiss"},
             {"appletviewer.tool.title", "Applet Viewer: {0}"},
             {"appletviewer.menu.applet", "Applet"},
@@ -197,5 +197,7 @@
             {"appletsecurityexception.checkread.unknown", "unknown class loader type. unable to check for checking read {0}"},
             {"appletsecurityexception.checkconnect.unknown", "unknown class loader type. unable to check for checking connect"},
         };
+
+        return temp;
     }
 }
--- a/jdk/src/share/classes/sun/java2d/pisces/Dasher.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/java2d/pisces/Dasher.java	Thu Sep 02 12:17:21 2010 -0700
@@ -36,117 +36,71 @@
  * semantics are unclear.
  *
  */
-public class Dasher extends LineSink {
+public class Dasher implements LineSink {
+    private final LineSink output;
+    private final float[] dash;
+    private final float startPhase;
+    private final boolean startDashOn;
+    private final int startIdx;
 
-    LineSink output;
-    int[] dash;
-    int startPhase;
-    boolean startDashOn;
-    int startIdx;
-
-    int idx;
-    boolean dashOn;
-    int phase;
-
-    int sx, sy;
-    int x0, y0;
+    private final float m00, m10, m01, m11;
+    private final float det;
 
-    int m00, m01;
-    int m10, m11;
-
-    Transform4 transform;
-
-    boolean symmetric;
-    long ldet;
+    private boolean firstDashOn;
+    private boolean starting;
 
-    boolean firstDashOn;
-    boolean starting;
-    int sx1, sy1;
+    private int idx;
+    private boolean dashOn;
+    private float phase;
 
-    /**
-     * Empty constructor.  <code>setOutput</code> and
-     * <code>setParameters</code> must be called prior to calling any
-     * other methods.
-     */
-    public Dasher() {}
+    private float sx, sy;
+    private float x0, y0;
+    private float sx1, sy1;
+
 
     /**
      * Constructs a <code>Dasher</code>.
      *
      * @param output an output <code>LineSink</code>.
-     * @param dash an array of <code>int</code>s containing the dash
-     * pattern in S15.16 format.
-     * @param phase an <code>int</code> containing the dash phase in
-     * S15.16 format.
+     * @param dash an array of <code>int</code>s containing the dash pattern
+     * @param phase an <code>int</code> containing the dash phase
      * @param transform a <code>Transform4</code> object indicating
      * the transform that has been previously applied to all incoming
      * coordinates.  This is required in order to compute dash lengths
      * properly.
      */
     public Dasher(LineSink output,
-                  int[] dash, int phase,
-                  Transform4 transform) {
-        setOutput(output);
-        setParameters(dash, phase, transform);
-    }
-
-    /**
-     * Sets the output <code>LineSink</code> of this
-     * <code>Dasher</code>.
-     *
-     * @param output an output <code>LineSink</code>.
-     */
-    public void setOutput(LineSink output) {
-        this.output = output;
-    }
-
-    /**
-     * Sets the parameters of this <code>Dasher</code>.
-     *
-     * @param dash an array of <code>int</code>s containing the dash
-     * pattern in S15.16 format.
-     * @param phase an <code>int</code> containing the dash phase in
-     * S15.16 format.
-     * @param transform a <code>Transform4</code> object indicating
-     * the transform that has been previously applied to all incoming
-     * coordinates.  This is required in order to compute dash lengths
-     * properly.
-     */
-    public void setParameters(int[] dash, int phase,
-                              Transform4 transform) {
+                  float[] dash, float phase,
+                  float a00, float a01, float a10, float a11) {
         if (phase < 0) {
             throw new IllegalArgumentException("phase < 0 !");
         }
 
+        this.output = output;
+
         // Normalize so 0 <= phase < dash[0]
         int idx = 0;
         dashOn = true;
-        int d;
+        float d;
         while (phase >= (d = dash[idx])) {
             phase -= d;
             idx = (idx + 1) % dash.length;
             dashOn = !dashOn;
         }
 
-        this.dash = new int[dash.length];
-        for (int i = 0; i < dash.length; i++) {
-            this.dash[i] = dash[i];
-        }
+        this.dash = dash;
         this.startPhase = this.phase = phase;
         this.startDashOn = dashOn;
         this.startIdx = idx;
 
-        this.transform = transform;
-
-        this.m00 = transform.m00;
-        this.m01 = transform.m01;
-        this.m10 = transform.m10;
-        this.m11 = transform.m11;
-        this.ldet = ((long)m00*m11 - (long)m01*m10) >> 16;
-        this.symmetric = (m00 == m11 && m10 == -m01);
+        m00 = a00;
+        m01 = a01;
+        m10 = a10;
+        m11 = a11;
+        det = m00 * m11 - m01 * m10;
     }
 
-    public void moveTo(int x0, int y0) {
+    public void moveTo(float x0, float y0) {
         output.moveTo(x0, y0);
         this.idx = startIdx;
         this.dashOn = this.startDashOn;
@@ -160,7 +114,7 @@
         output.lineJoin();
     }
 
-    private void goTo(int x1, int y1) {
+    private void goTo(float x1, float y1) {
         if (dashOn) {
             if (starting) {
                 this.sx1 = x1;
@@ -180,52 +134,64 @@
         this.y0 = y1;
     }
 
-    public void lineTo(int x1, int y1) {
-        while (true) {
-            int d = dash[idx] - phase;
-            int lx = x1 - x0;
-            int ly = y1 - y0;
+    public void lineTo(float x1, float y1) {
+        // The widened line is squished to a 0 width one, so no drawing is done
+        if (det == 0) {
+            goTo(x1, y1);
+            return;
+        }
+        float dx = x1 - x0;
+        float dy = y1 - y0;
 
-            // Compute segment length in the untransformed
-            // coordinate system
-            // IMPL NOTE - use fixed point
+
+        // Compute segment length in the untransformed
+        // coordinate system
 
-            int l;
-            if (symmetric) {
-                l = (int)((PiscesMath.hypot(lx, ly)*65536L)/ldet);
-            } else{
-                long la = ((long)ly*m00 - (long)lx*m10)/ldet;
-                long lb = ((long)ly*m01 - (long)lx*m11)/ldet;
-                l = (int)PiscesMath.hypot(la, lb);
-            }
+        float la = (dy*m00 - dx*m10)/det;
+        float lb = (dy*m01 - dx*m11)/det;
+        float origLen = (float) Math.hypot(la, lb);
 
-            if (l < d) {
+        if (origLen == 0) {
+            // Let the output LineSink deal with cases where dx, dy are 0.
+            goTo(x1, y1);
+            return;
+        }
+
+        // The scaling factors needed to get the dx and dy of the
+        // transformed dash segments.
+        float cx = dx / origLen;
+        float cy = dy / origLen;
+
+        while (true) {
+            float leftInThisDashSegment = dash[idx] - phase;
+            if (origLen < leftInThisDashSegment) {
                 goTo(x1, y1);
                 // Advance phase within current dash segment
-                phase += l;
+                phase += origLen;
+                return;
+            } else if (origLen == leftInThisDashSegment) {
+                goTo(x1, y1);
+                phase = 0f;
+                idx = (idx + 1) % dash.length;
+                dashOn = !dashOn;
                 return;
             }
 
-            long t;
-            int xsplit, ysplit;
-//             // For zero length dashses, SE appears to move 1/8 unit
-//             // in device space
-//             if (d == 0) {
-//                 double dlx = lx/65536.0;
-//                 double dly = ly/65536.0;
-//                 len = PiscesMath.hypot(dlx, dly);
-//                 double dt = 1.0/(8*len);
-//                 double dxsplit = (x0/65536.0) + dt*dlx;
-//                 double dysplit = (y0/65536.0) + dt*dly;
-//                 xsplit = (int)(dxsplit*65536.0);
-//                 ysplit = (int)(dysplit*65536.0);
-//             } else {
-                t = ((long)d << 16)/l;
-                xsplit = x0 + (int)(t*(x1 - x0) >> 16);
-                ysplit = y0 + (int)(t*(y1 - y0) >> 16);
-//             }
-            goTo(xsplit, ysplit);
+            float dashx, dashy;
+            float dashdx = dash[idx] * cx;
+            float dashdy = dash[idx] * cy;
+            if (phase == 0) {
+                dashx = x0 + dashdx;
+                dashy = y0 + dashdy;
+            } else {
+                float p = (leftInThisDashSegment) / dash[idx];
+                dashx = x0 + p * dashdx;
+                dashy = y0 + p * dashdy;
+            }
 
+            goTo(dashx, dashy);
+
+            origLen -= (dash[idx] - phase);
             // Advance to next dash segment
             idx = (idx + 1) % dash.length;
             dashOn = !dashOn;
@@ -233,6 +199,7 @@
         }
     }
 
+
     public void close() {
         lineTo(sx, sy);
         if (firstDashOn) {
--- a/jdk/src/share/classes/sun/java2d/pisces/LineSink.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/java2d/pisces/LineSink.java	Thu Sep 02 12:17:21 2010 -0700
@@ -39,16 +39,16 @@
  * <code>LineSink</code> interface.
  *
  */
-public abstract class LineSink {
+public interface LineSink {
 
     /**
      * Moves the current drawing position to the point <code>(x0,
      * y0)</code>.
      *
-     * @param x0 the X coordinate in S15.16 format
-     * @param y0 the Y coordinate in S15.16 format
+     * @param x0 the X coordinate
+     * @param y0 the Y coordinate
      */
-    public abstract void moveTo(int x0, int y0);
+    public void moveTo(float x0, float y0);
 
     /**
      * Provides a hint that the current segment should be joined to
@@ -65,29 +65,29 @@
      * <p> Other <code>LineSink</code> classes should simply pass this
      * hint to their output sink as needed.
      */
-    public abstract void lineJoin();
+    public void lineJoin();
 
     /**
      * Draws a line from the current drawing position to the point
      * <code>(x1, y1)</code> and sets the current drawing position to
      * <code>(x1, y1)</code>.
      *
-     * @param x1 the X coordinate in S15.16 format
-     * @param y1 the Y coordinate in S15.16 format
+     * @param x1 the X coordinate
+     * @param y1 the Y coordinate
      */
-    public abstract void lineTo(int x1, int y1);
+    public void lineTo(float x1, float y1);
 
     /**
      * Closes the current path by drawing a line from the current
      * drawing position to the point specified by the moset recent
      * <code>moveTo</code> command.
      */
-    public abstract void close();
+    public void close();
 
     /**
      * Ends the current path.  It may be necessary to end a path in
      * order to allow end caps to be drawn.
      */
-    public abstract void end();
+    public void end();
 
 }
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesMath.java	Tue Aug 31 15:05:09 2010 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.java2d.pisces;
-
-public class PiscesMath {
-
-    private PiscesMath() {}
-
-    private static final int SINTAB_LG_ENTRIES = 10;
-    private static final int SINTAB_ENTRIES = 1 << SINTAB_LG_ENTRIES;
-    private static int[] sintab;
-
-    public static final int PI = (int)(Math.PI*65536.0);
-    public static final int TWO_PI = (int)(2.0*Math.PI*65536.0);
-    public static final int PI_OVER_TWO = (int)((Math.PI/2.0)*65536.0);
-    public static final int SQRT_TWO = (int)(Math.sqrt(2.0)*65536.0);
-
-    static {
-        sintab = new int[SINTAB_ENTRIES + 1];
-        for (int i = 0; i < SINTAB_ENTRIES + 1; i++) {
-            double theta = i*(Math.PI/2.0)/SINTAB_ENTRIES;
-            sintab[i] = (int)(Math.sin(theta)*65536.0);
-        }
-    }
-
-    public static int sin(int theta) {
-        int sign = 1;
-        if (theta < 0) {
-            theta = -theta;
-            sign = -1;
-        }
-        // 0 <= theta
-        while (theta >= TWO_PI) {
-            theta -= TWO_PI;
-        }
-        // 0 <= theta < 2*PI
-        if (theta >= PI) {
-            theta = TWO_PI - theta;
-            sign = -sign;
-        }
-        // 0 <= theta < PI
-        if (theta > PI_OVER_TWO) {
-            theta = PI - theta;
-        }
-        // 0 <= theta <= PI/2
-        int itheta = (int)((long)theta*SINTAB_ENTRIES/(PI_OVER_TWO));
-        return sign*sintab[itheta];
-    }
-
-    public static int cos(int theta) {
-        return sin(PI_OVER_TWO - theta);
-    }
-
-//     public static double sqrt(double x) {
-//         double dsqrt = Math.sqrt(x);
-//         int ix = (int)(x*65536.0);
-//         Int Isqrt = Isqrt(Ix);
-
-//         Long Lx = (Long)(X*65536.0);
-//         Long Lsqrt = Lsqrt(Lx);
-
-//         System.Out.Println();
-//         System.Out.Println("X = " + X);
-//         System.Out.Println("Dsqrt = " + Dsqrt);
-
-//         System.Out.Println("Ix = " + Ix);
-//         System.Out.Println("Isqrt = " + Isqrt/65536.0);
-
-//         System.Out.Println("Lx = " + Lx);
-//         System.Out.Println("Lsqrt = " + Lsqrt/65536.0);
-
-//         Return Dsqrt;
-//     }
-
-    // From Ken Turkowski, _Fixed-Point Square Root_, In Graphics Gems V
-    public static int isqrt(int x) {
-        int fracbits = 16;
-
-        int root = 0;
-        int remHi = 0;
-        int remLo = x;
-        int count = 15 + fracbits/2;
-
-        do {
-            remHi = (remHi << 2) | (remLo >>> 30); // N.B. - unsigned shift R
-            remLo <<= 2;
-            root <<= 1;
-            int testdiv = (root << 1) + 1;
-            if (remHi >= testdiv) {
-                remHi -= testdiv;
-                root++;
-            }
-        } while (count-- != 0);
-
-        return root;
-    }
-
-    public static long lsqrt(long x) {
-        int fracbits = 16;
-
-        long root = 0;
-        long remHi = 0;
-        long remLo = x;
-        int count = 31 + fracbits/2;
-
-        do {
-            remHi = (remHi << 2) | (remLo >>> 62); // N.B. - unsigned shift R
-            remLo <<= 2;
-            root <<= 1;
-            long testDiv = (root << 1) + 1;
-            if (remHi >= testDiv) {
-                remHi -= testDiv;
-                root++;
-            }
-        } while (count-- != 0);
-
-        return root;
-    }
-
-    public static double hypot(double x, double y) {
-        // new RuntimeException().printStackTrace();
-        return Math.sqrt(x*x + y*y);
-    }
-
-    public static int hypot(int x, int y) {
-        return (int)((lsqrt((long)x*x + (long)y*y) + 128) >> 8);
-    }
-
-    public static long hypot(long x, long y) {
-        return (lsqrt(x*x + y*y) + 128) >> 8;
-    }
-}
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Thu Sep 02 12:17:21 2010 -0700
@@ -27,6 +27,7 @@
 
 import java.awt.Shape;
 import java.awt.BasicStroke;
+import java.awt.geom.FlatteningPathIterator;
 import java.awt.geom.Path2D;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.PathIterator;
@@ -37,23 +38,9 @@
 import sun.java2d.pipe.AATileGenerator;
 
 public class PiscesRenderingEngine extends RenderingEngine {
-    public static Transform4 IdentT4 = new Transform4();
     public static double defaultFlat = 0.1;
 
-    static int FloatToS15_16(float flt) {
-        flt = flt * 65536f + 0.5f;
-        if (flt <= -(65536f * 65536f)) {
-            return Integer.MIN_VALUE;
-        } else if (flt >= (65536f * 65536f)) {
-            return Integer.MAX_VALUE;
-        } else {
-            return (int) Math.floor(flt);
-        }
-    }
-
-    static float S15_16ToFloat(int fix) {
-        return (fix / 65536f);
-    }
+    private static enum NormMode {OFF, ON_NO_AA, ON_WITH_AA}
 
     /**
      * Create a widened path as specified by the parameters.
@@ -85,18 +72,19 @@
         strokeTo(src,
                  null,
                  width,
+                 NormMode.OFF,
                  caps,
                  join,
                  miterlimit,
                  dashes,
                  dashphase,
                  new LineSink() {
-                     public void moveTo(int x0, int y0) {
-                         p2d.moveTo(S15_16ToFloat(x0), S15_16ToFloat(y0));
+                     public void moveTo(float x0, float y0) {
+                         p2d.moveTo(x0, y0);
                      }
                      public void lineJoin() {}
-                     public void lineTo(int x1, int y1) {
-                         p2d.lineTo(S15_16ToFloat(x1), S15_16ToFloat(y1));
+                     public void lineTo(float x1, float y1) {
+                         p2d.lineTo(x1, y1);
                      }
                      public void close() {
                          p2d.closePath();
@@ -142,14 +130,17 @@
                          boolean antialias,
                          final PathConsumer2D consumer)
     {
-        strokeTo(src, at, bs, thin, normalize, antialias,
+        NormMode norm = (normalize) ?
+                ((antialias) ? NormMode.ON_WITH_AA : NormMode.ON_NO_AA)
+                : NormMode.OFF;
+        strokeTo(src, at, bs, thin, norm, antialias,
                  new LineSink() {
-                     public void moveTo(int x0, int y0) {
-                         consumer.moveTo(S15_16ToFloat(x0), S15_16ToFloat(y0));
+                     public void moveTo(float x0, float y0) {
+                         consumer.moveTo(x0, y0);
                      }
                      public void lineJoin() {}
-                     public void lineTo(int x1, int y1) {
-                         consumer.lineTo(S15_16ToFloat(x1), S15_16ToFloat(y1));
+                     public void lineTo(float x1, float y1) {
+                         consumer.lineTo(x1, y1);
                      }
                      public void close() {
                          consumer.closePath();
@@ -164,7 +155,7 @@
                   AffineTransform at,
                   BasicStroke bs,
                   boolean thin,
-                  boolean normalize,
+                  NormMode normalize,
                   boolean antialias,
                   LineSink lsink)
     {
@@ -181,6 +172,7 @@
         strokeTo(src,
                  at,
                  lw,
+                 normalize,
                  bs.getEndCap(),
                  bs.getLineJoin(),
                  bs.getMiterLimit(),
@@ -258,6 +250,7 @@
     void strokeTo(Shape src,
                   AffineTransform at,
                   float width,
+                  NormMode normalize,
                   int caps,
                   int join,
                   float miterlimit,
@@ -265,36 +258,139 @@
                   float dashphase,
                   LineSink lsink)
     {
-        Transform4 t4;
-
-        if (at == null || at.isIdentity()) {
-            t4 = IdentT4;
+        float a00 = 1f, a01 = 0f, a10 = 0f, a11 = 1f;
+        if (at != null && !at.isIdentity()) {
+            a00 = (float)at.getScaleX();
+            a01 = (float)at.getShearX();
+            a10 = (float)at.getShearY();
+            a11 = (float)at.getScaleY();
+        }
+        lsink = new Stroker(lsink, width, caps, join, miterlimit, a00, a01, a10, a11);
+        if (dashes != null) {
+            lsink = new Dasher(lsink, dashes, dashphase, a00, a01, a10, a11);
+        }
+        PathIterator pi;
+        if (normalize != NormMode.OFF) {
+            pi = new FlatteningPathIterator(
+                    new NormalizingPathIterator(src.getPathIterator(at), normalize),
+                    defaultFlat);
         } else {
-            t4 = new Transform4(FloatToS15_16((float) at.getScaleX()),
-                                FloatToS15_16((float) at.getShearX()),
-                                FloatToS15_16((float) at.getShearY()),
-                                FloatToS15_16((float) at.getScaleY()));
+            pi = src.getPathIterator(at, defaultFlat);
+        }
+        pathTo(pi, lsink);
+    }
+
+    private static class NormalizingPathIterator implements PathIterator {
+
+        private final PathIterator src;
+
+        // the adjustment applied to the current position.
+        private float curx_adjust, cury_adjust;
+        // the adjustment applied to the last moveTo position.
+        private float movx_adjust, movy_adjust;
+
+        // constants used in normalization computations
+        private final float lval, rval;
+
+        NormalizingPathIterator(PathIterator src, NormMode mode) {
+            this.src = src;
+            switch (mode) {
+            case ON_NO_AA:
+                // round to nearest (0.25, 0.25) pixel
+                lval = rval = 0.25f;
+                break;
+            case ON_WITH_AA:
+                // round to nearest pixel center
+                lval = 0f;
+                rval = 0.5f;
+                break;
+            case OFF:
+                throw new InternalError("A NormalizingPathIterator should " +
+                         "not be created if no normalization is being done");
+            default:
+                throw new InternalError("Unrecognized normalization mode");
+            }
         }
 
-        lsink = new Stroker(lsink,
-                            FloatToS15_16(width),
-                            caps,
-                            join,
-                            FloatToS15_16(miterlimit),
-                            t4);
-        if (dashes != null) {
-            int fdashes[] = new int[dashes.length];
-            for (int i = 0; i < dashes.length; i++) {
-                fdashes[i] = FloatToS15_16(dashes[i]);
+        public int currentSegment(float[] coords) {
+            int type = src.currentSegment(coords);
+
+            int lastCoord;
+            switch(type) {
+            case PathIterator.SEG_CUBICTO:
+                lastCoord = 4;
+                break;
+            case PathIterator.SEG_QUADTO:
+                lastCoord = 2;
+                break;
+            case PathIterator.SEG_LINETO:
+            case PathIterator.SEG_MOVETO:
+                lastCoord = 0;
+                break;
+            case PathIterator.SEG_CLOSE:
+                // we don't want to deal with this case later. We just exit now
+                curx_adjust = movx_adjust;
+                cury_adjust = movy_adjust;
+                return type;
+            default:
+                throw new InternalError("Unrecognized curve type");
             }
-            lsink = new Dasher(lsink,
-                               fdashes,
-                               FloatToS15_16(dashphase),
-                               t4);
+
+            // normalize endpoint
+            float x_adjust = (float)Math.floor(coords[lastCoord] + lval) + rval -
+                         coords[lastCoord];
+            float y_adjust = (float)Math.floor(coords[lastCoord+1] + lval) + rval -
+                         coords[lastCoord + 1];
+
+            coords[lastCoord    ] += x_adjust;
+            coords[lastCoord + 1] += y_adjust;
+
+            // now that the end points are done, normalize the control points
+            switch(type) {
+            case PathIterator.SEG_CUBICTO:
+                coords[0] += curx_adjust;
+                coords[1] += cury_adjust;
+                coords[2] += x_adjust;
+                coords[3] += y_adjust;
+                break;
+            case PathIterator.SEG_QUADTO:
+                coords[0] += (curx_adjust + x_adjust) / 2;
+                coords[1] += (cury_adjust + y_adjust) / 2;
+                break;
+            case PathIterator.SEG_LINETO:
+                break;
+            case PathIterator.SEG_MOVETO:
+                movx_adjust = x_adjust;
+                movy_adjust = y_adjust;
+                break;
+            case PathIterator.SEG_CLOSE:
+                throw new InternalError("This should be handled earlier.");
+            }
+            curx_adjust = x_adjust;
+            cury_adjust = y_adjust;
+            return type;
         }
 
-        PathIterator pi = src.getPathIterator(at, defaultFlat);
-        pathTo(pi, lsink);
+        public int currentSegment(double[] coords) {
+            float[] tmp = new float[6];
+            int type = this.currentSegment(tmp);
+            for (int i = 0; i < 6; i++) {
+                coords[i] = (float) tmp[i];
+            }
+            return type;
+        }
+
+        public int getWindingRule() {
+            return src.getWindingRule();
+        }
+
+        public boolean isDone() {
+            return src.isDone();
+        }
+
+        public void next() {
+            src.next();
+        }
     }
 
     void pathTo(PathIterator pi, LineSink lsink) {
@@ -302,13 +398,11 @@
         while (!pi.isDone()) {
             switch (pi.currentSegment(coords)) {
             case PathIterator.SEG_MOVETO:
-                lsink.moveTo(FloatToS15_16(coords[0]),
-                             FloatToS15_16(coords[1]));
+                lsink.moveTo(coords[0], coords[1]);
                 break;
             case PathIterator.SEG_LINETO:
                 lsink.lineJoin();
-                lsink.lineTo(FloatToS15_16(coords[0]),
-                             FloatToS15_16(coords[1]));
+                lsink.lineTo(coords[0], coords[1]);
                 break;
             case PathIterator.SEG_CLOSE:
                 lsink.lineJoin();
@@ -378,18 +472,28 @@
                                               int bbox[])
     {
         PiscesCache pc = PiscesCache.createInstance();
-        Renderer r = new Renderer();
-        r.setCache(pc);
-        r.setAntialiasing(3, 3);
-        r.beginRendering(clip.getLoX(), clip.getLoY(),
-                         clip.getWidth(), clip.getHeight());
+        Renderer r;
+        NormMode norm = (normalize) ? NormMode.ON_WITH_AA : NormMode.OFF;
         if (bs == null) {
-            PathIterator pi = s.getPathIterator(at, defaultFlat);
-            r.setWindingRule(pi.getWindingRule());
+            PathIterator pi;
+            if (normalize) {
+                pi = new FlatteningPathIterator(
+                        new NormalizingPathIterator(s.getPathIterator(at), norm),
+                        defaultFlat);
+            } else {
+                pi = s.getPathIterator(at, defaultFlat);
+            }
+            r = new Renderer(3, 3,
+                             clip.getLoX(), clip.getLoY(),
+                             clip.getWidth(), clip.getHeight(),
+                             pi.getWindingRule(), pc);
             pathTo(pi, r);
         } else {
-            r.setWindingRule(PathIterator.WIND_NON_ZERO);
-            strokeTo(s, at, bs, thin, normalize, true, r);
+            r = new Renderer(3, 3,
+                             clip.getLoX(), clip.getLoY(),
+                             clip.getWidth(), clip.getHeight(),
+                             PathIterator.WIND_NON_ZERO, pc);
+            strokeTo(s, at, bs, thin, norm, true, r);
         }
         r.endRendering();
         PiscesTileGenerator ptg = new PiscesTileGenerator(pc, r.MAX_AA_ALPHA);
@@ -420,3 +524,4 @@
         }
     }
 }
+
--- a/jdk/src/share/classes/sun/java2d/pisces/Renderer.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/java2d/pisces/Renderer.java	Thu Sep 02 12:17:21 2010 -0700
@@ -25,446 +25,440 @@
 
 package sun.java2d.pisces;
 
-public class Renderer extends LineSink {
+import java.util.Arrays;
+
+public class Renderer implements LineSink {
+
+///////////////////////////////////////////////////////////////////////////////
+// Scan line iterator and edge crossing data.
+//////////////////////////////////////////////////////////////////////////////
+
+    private int[] crossings;
+
+    // This is an array of indices into the edge array. It is initialized to
+    // [i * SIZEOF_STRUCT_EDGE for i in range(0, edgesSize/SIZEOF_STRUCT_EDGE)]
+    // (where range(i, j) is i,i+1,...,j-1 -- just like in python).
+    // The reason for keeping this is because we need the edges array sorted
+    // by y0, but we don't want to move all that data around, so instead we
+    // sort the indices into the edge array, and use edgeIndices to access
+    // the edges array. This is meant to simulate a pointer array (hence the name)
+    private int[] edgePtrs;
+
+    // crossing bounds. The bounds are not necessarily tight (the scan line
+    // at minY, for example, might have no crossings). The x bounds will
+    // be accumulated as crossings are computed.
+    private int minY, maxY;
+    private int minX, maxX;
+    private int nextY;
+
+    // indices into the edge pointer list. They indicate the "active" sublist in
+    // the edge list (the portion of the list that contains all the edges that
+    // cross the next scan line).
+    private int lo, hi;
+
+    private static final int INIT_CROSSINGS_SIZE = 50;
+    private void ScanLineItInitialize() {
+        crossings = new int[INIT_CROSSINGS_SIZE];
+        edgePtrs = new int[edgesSize / SIZEOF_STRUCT_EDGE];
+        for (int i = 0; i < edgePtrs.length; i++) {
+            edgePtrs[i] = i * SIZEOF_STRUCT_EDGE;
+        }
+
+        qsort(0, edgePtrs.length - 1);
+
+        // We don't care if we clip some of the line off with ceil, since
+        // no scan line crossings will be eliminated (in fact, the ceil is
+        // the y of the first scan line crossing).
+        nextY = minY = Math.max(boundsMinY, (int)Math.ceil(edgeMinY));
+        maxY = Math.min(boundsMaxY, (int)Math.ceil(edgeMaxY));
+
+        for (lo = 0; lo < edgePtrs.length && edges[edgePtrs[lo]+Y1] <= nextY; lo++)
+            ;
+        for (hi = lo; hi < edgePtrs.length && edges[edgePtrs[hi]+CURY] <= nextY; hi++)
+            ; // the active list is *edgePtrs[lo] (inclusive) *edgePtrs[hi] (exclusive)
+        for (int i = lo; i < hi; i++) {
+            setCurY(edgePtrs[i], nextY);
+        }
+
+        // We accumulate X in the iterator because accumulating it in addEdge
+        // like we do with Y does not do much good: if there's an edge
+        // (0,0)->(1000,10000), and if y gets clipped to 1000, then the x
+        // bound should be 100, but the accumulator from addEdge would say 1000,
+        // so we'd still have to accumulate the X bounds as we add crossings.
+        minX = boundsMinX;
+        maxX = boundsMaxX;
+    }
+
+    private int ScanLineItCurrentY() {
+        return nextY - 1;
+    }
+
+    private int ScanLineItGoToNextYAndComputeCrossings() {
+        // we go through the active list and remove the ones that don't cross
+        // the nextY scanline.
+        int crossingIdx = 0;
+        for (int i = lo; i < hi; i++) {
+            if (edges[edgePtrs[i]+Y1] <= nextY) {
+                edgePtrs[i] = edgePtrs[lo++];
+            }
+        }
+        if (hi - lo > crossings.length) {
+            int newSize = Math.max(hi - lo, crossings.length * 2);
+            crossings = Arrays.copyOf(crossings, newSize);
+        }
+        // Now every edge between lo and hi crosses nextY. Compute it's
+        // crossing and put it in the crossings array.
+        for (int i = lo; i < hi; i++) {
+            addCrossing(nextY, getCurCrossing(edgePtrs[i]), (int)edges[edgePtrs[i]+OR], crossingIdx);
+            gotoNextY(edgePtrs[i]);
+            crossingIdx++;
+        }
+
+        nextY++;
+        // Expand active list to include new edges.
+        for (; hi < edgePtrs.length && edges[edgePtrs[hi]+CURY] <= nextY; hi++) {
+            setCurY(edgePtrs[hi], nextY);
+        }
+
+        Arrays.sort(crossings, 0, crossingIdx);
+        return crossingIdx;
+    }
+
+    private boolean ScanLineItHasNext() {
+        return nextY < maxY;
+    }
+
+    private void addCrossing(int y, int x, int or, int idx) {
+        if (x < minX) {
+            minX = x;
+        }
+        if (x > maxX) {
+            maxX = x;
+        }
+        x <<= 1;
+        crossings[idx] = ((or == 1) ? (x | 0x1) : x);
+    }
+
+
+    // quicksort implementation for sorting the edge indices ("pointers")
+    // by increasing y0. first, last are indices into the "pointer" array
+    // It sorts the pointer array from first (inclusive) to last (inclusive)
+    private void qsort(int first, int last) {
+        if (last > first) {
+            int p = partition(first, last);
+            if (first < p - 1) {
+                qsort(first, p - 1);
+            }
+            if (p < last) {
+                qsort(p, last);
+            }
+        }
+    }
+
+    // i, j are indices into edgePtrs.
+    private int partition(int i, int j) {
+        int pivotVal = edgePtrs[i];
+        while (i <= j) {
+            // edges[edgePtrs[i]+1] is equivalent to (*(edgePtrs[i])).y0 in C
+            while (edges[edgePtrs[i]+CURY] < edges[pivotVal+CURY]) { i++; }
+            while (edges[edgePtrs[j]+CURY] > edges[pivotVal+CURY]) { j--; }
+            if (i <= j) {
+                int tmp = edgePtrs[i];
+                edgePtrs[i] = edgePtrs[j];
+                edgePtrs[j] = tmp;
+                i++;
+                j--;
+            }
+        }
+        return i;
+    }
+
+//============================================================================
+
+
+//////////////////////////////////////////////////////////////////////////////
+//  EDGE LIST
+//////////////////////////////////////////////////////////////////////////////
+
+    private static final int INIT_NUM_EDGES = 1000;
+    private static final int SIZEOF_STRUCT_EDGE = 5;
+
+    // The following array is a poor man's struct array:
+    // it simulates a struct array by having
+    // edges[SIZEOF_STRUCT_EDGE * i + j] be the jth field in the ith element
+    // of an array of edge structs.
+    private float[] edges;
+    private int edgesSize; // size of the edge list.
+    private static final int Y1    = 0;
+    private static final int SLOPE = 1;
+    private static final int OR    = 2; // the orientation. This can be -1 or 1.
+                                     // -1 means up, 1 means down.
+    private static final int CURY  = 3; // j = 5 corresponds to the "current Y".
+                             // Each edge keeps track of the last scanline
+                             // crossing it computed, and this is the y coord of
+                             // that scanline.
+    private static final int CURX = 4; //the x coord of the current crossing.
+
+    // Note that while the array is declared as a float[] not all of it's
+    // elements should be floats. currentY and Orientation should be ints (or int and
+    // byte respectively), but they all need to be the same type. This isn't
+    // really a problem because floats can represent exactly all 23 bit integers,
+    // which should be more than enough.
+    // Note, also, that we only need x1 for slope computation, so we don't need
+    // to store it. x0, y0 don't need to be stored either. They can be put into
+    // curx, cury, and it's ok if they're lost when curx and cury are changed.
+    // We take this undeniably ugly and error prone approach (instead of simply
+    // making an Edge class) for performance reasons. Also, it would probably be nicer
+    // to have one array for each field, but that would defeat the purpose because
+    // it would make poor use of the processor cache, since we tend to access
+    // all the fields for one edge at a time.
+
+    private float edgeMinY;
+    private float edgeMaxY;
+
+
+    private void addEdge(float x0, float y0, float x1, float y1) {
+        float or = (y0 < y1) ? 1f : -1f; // orientation: 1 = UP; -1 = DOWN
+        if (or == -1) {
+            float tmp = y0;
+            y0 = y1;
+            y1 = tmp;
+            tmp = x0;
+            x0 = x1;
+            x1 = tmp;
+        }
+        // skip edges that don't cross a scanline
+        if (Math.ceil(y0) >= Math.ceil(y1)) {
+            return;
+        }
+
+        int newSize = edgesSize + SIZEOF_STRUCT_EDGE;
+        if (edges.length < newSize) {
+            edges = Arrays.copyOf(edges, newSize * 2);
+        }
+        edges[edgesSize+CURX] = x0;
+        edges[edgesSize+CURY] = y0;
+        edges[edgesSize+Y1] = y1;
+        edges[edgesSize+SLOPE] = (x1 - x0) / (y1 - y0);
+        edges[edgesSize+OR] = or;
+        // the crossing values can't be initialized meaningfully yet. This
+        // will have to wait until setCurY is called
+        edgesSize += SIZEOF_STRUCT_EDGE;
+
+        // Accumulate edgeMinY and edgeMaxY
+        if (y0 < edgeMinY) { edgeMinY = y0; }
+        if (y1 > edgeMaxY) { edgeMaxY = y1; }
+    }
+
+    // As far as the following methods care, this edges extends to infinity.
+    // They can compute the x intersect of any horizontal line.
+    // precondition: idx is the index to the start of the desired edge.
+    // So, if the ith edge is wanted, idx should be SIZEOF_STRUCT_EDGE * i
+    private void setCurY(int idx, int y) {
+        // compute the x crossing of edge at idx and horizontal line y
+        // currentXCrossing = (y - y0)*slope + x0
+        edges[idx + CURX] = (y - edges[idx + CURY]) * edges[idx + SLOPE] + edges[idx+CURX];
+        edges[idx + CURY] = (float)y;
+    }
+
+    private void gotoNextY(int idx) {
+        edges[idx + CURY] += 1f; // i.e. curY += 1
+        edges[idx + CURX] += edges[idx + SLOPE]; // i.e. curXCrossing += slope
+    }
+
+    private int getCurCrossing(int idx) {
+        return (int)edges[idx + CURX];
+    }
+//====================================================================================
+
     public static final int WIND_EVEN_ODD = 0;
     public static final int WIND_NON_ZERO = 1;
 
-    // Initial edge list size
-    // IMPL_NOTE - restore size after growth
-    public static final int INITIAL_EDGES = 1000;
-
-    // Recommended maximum scratchpad sizes.  The arrays will grow
-    // larger if needed, but when finished() is called they will be released
-    // if they have grown larger than these sizes.
-    public static final int DEFAULT_INDICES_SIZE = 8192;
-    public static final int DEFAULT_CROSSINGS_SIZE = 32*1024;
-
     // Antialiasing
-    private int SUBPIXEL_LG_POSITIONS_X;
-    private int SUBPIXEL_LG_POSITIONS_Y;
-    private int SUBPIXEL_MASK_X;
-    private int SUBPIXEL_MASK_Y;
-    private int SUBPIXEL_POSITIONS_X;
-    private int SUBPIXEL_POSITIONS_Y;
-    int MAX_AA_ALPHA;
-    private int MAX_AA_ALPHA_DENOM;
-    private int HALF_MAX_AA_ALPHA_DENOM;
-    private int XSHIFT;
-    private int YSHIFT;
-    private int YSTEP;
-    private int HYSTEP;
-    private int YMASK;
-
-    private static final int MIN_QUAD_OPT_WIDTH = 100 << 16;
+    final private int SUBPIXEL_LG_POSITIONS_X;
+    final private int SUBPIXEL_LG_POSITIONS_Y;
+    final private int SUBPIXEL_POSITIONS_X;
+    final private int SUBPIXEL_POSITIONS_Y;
+    final private int SUBPIXEL_MASK_X;
+    final private int SUBPIXEL_MASK_Y;
+    final int MAX_AA_ALPHA;
 
     // Cache to store RLE-encoded coverage mask of the current primitive
-    PiscesCache cache;
+    final PiscesCache cache;
 
-    // Bounds of the drawing region, at S15.16 precsion
-    private int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY;
-
-    // Bounds of the current primitive, at subsample precision
-    private int rasterMinX, rasterMaxX, rasterMinY, rasterMaxY;
+    // Bounds of the drawing region, at subpixel precision.
+    final private int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY;
 
     // Pixel bounding box for current primitive
-    private int bboxX0, bboxY0, bboxX1, bboxY1;
+    private int pix_bboxX0, pix_bboxY0, pix_bboxX1, pix_bboxY1;
 
     // Current winding rule
-    private int windingRule;
+    final private int windingRule;
 
     // Current drawing position, i.e., final point of last segment
-    private int x0, y0;
+    private float x0, y0;
 
     // Position of most recent 'moveTo' command
-    private int sx0, sy0;
-
-    // Buffer to be filled with one row's worth of alpha values
-    private byte[] rowAA; // needs to be short if 16x16 subsampling
+    private float pix_sx0, pix_sy0;
 
-    // Track the number of vertical extrema of the incoming edge list
-    // in order to determine the maximum number of crossings of a
-    // scanline
-    private int firstOrientation;
-    private int lastOrientation;
-    private int flips;
-
-    // Parameters for emitRow
-    private int alphaWidth;
-
-    public Renderer() {
-    }
-
-    public void setAntialiasing(int subpixelLgPositionsX,
-                                int subpixelLgPositionsY) {
+    public Renderer(int subpixelLgPositionsX, int subpixelLgPositionsY,
+                    int pix_boundsX, int pix_boundsY,
+                    int pix_boundsWidth, int pix_boundsHeight,
+                    int windingRule,
+                    PiscesCache cache) {
         this.SUBPIXEL_LG_POSITIONS_X = subpixelLgPositionsX;
         this.SUBPIXEL_LG_POSITIONS_Y = subpixelLgPositionsY;
+        this.SUBPIXEL_MASK_X = (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1;
+        this.SUBPIXEL_MASK_Y = (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1;
+        this.SUBPIXEL_POSITIONS_X = 1 << (SUBPIXEL_LG_POSITIONS_X);
+        this.SUBPIXEL_POSITIONS_Y = 1 << (SUBPIXEL_LG_POSITIONS_Y);
+        this.MAX_AA_ALPHA = (SUBPIXEL_POSITIONS_X * SUBPIXEL_POSITIONS_Y);
 
-        this.SUBPIXEL_MASK_X =
-            (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1;
-        this.SUBPIXEL_MASK_Y =
-            (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1;
-        this.SUBPIXEL_POSITIONS_X =
-            1 << (SUBPIXEL_LG_POSITIONS_X);
-        this.SUBPIXEL_POSITIONS_Y =
-            1 << (SUBPIXEL_LG_POSITIONS_Y);
-        this.MAX_AA_ALPHA =
-            (SUBPIXEL_POSITIONS_X*SUBPIXEL_POSITIONS_Y);
-        this.MAX_AA_ALPHA_DENOM = 255*MAX_AA_ALPHA;
-        this.HALF_MAX_AA_ALPHA_DENOM = MAX_AA_ALPHA_DENOM/2;
-        this.XSHIFT = 16 - SUBPIXEL_LG_POSITIONS_X;
-        this.YSHIFT = 16 - SUBPIXEL_LG_POSITIONS_Y;
-        this.YSTEP = 1 << YSHIFT;
-        this.HYSTEP = 1 << (YSHIFT - 1);
-        this.YMASK = ~(YSTEP - 1);
-    }
+        this.edges = new float[SIZEOF_STRUCT_EDGE * INIT_NUM_EDGES];
+        edgeMinY = Float.POSITIVE_INFINITY;
+        edgeMaxY = Float.NEGATIVE_INFINITY;
+        edgesSize = 0;
+
+        this.windingRule = windingRule;
+        this.cache = cache;
 
-    public int getSubpixelLgPositionsX() {
-        return SUBPIXEL_LG_POSITIONS_X;
-    }
+        this.boundsMinX = pix_boundsX * SUBPIXEL_POSITIONS_X;
+        this.boundsMinY = pix_boundsY * SUBPIXEL_POSITIONS_Y;
+        this.boundsMaxX = (pix_boundsX + pix_boundsWidth) * SUBPIXEL_POSITIONS_X;
+        this.boundsMaxY = (pix_boundsY + pix_boundsHeight) * SUBPIXEL_POSITIONS_Y;
 
-    public int getSubpixelLgPositionsY() {
-        return SUBPIXEL_LG_POSITIONS_Y;
-    }
-
-    public void setWindingRule(int windingRule) {
-        this.windingRule = windingRule;
-    }
-
-    public int getWindingRule() {
-        return windingRule;
+        this.pix_bboxX0 = pix_boundsX;
+        this.pix_bboxY0 = pix_boundsY;
+        this.pix_bboxX1 = pix_boundsX + pix_boundsWidth;
+        this.pix_bboxY1 = pix_boundsY + pix_boundsHeight;
     }
 
-    public void beginRendering(int boundsX, int boundsY,
-                               int boundsWidth, int boundsHeight) {
-        lastOrientation = 0;
-        flips = 0;
-
-        resetEdges();
-
-        this.boundsMinX = boundsX << 16;
-        this.boundsMinY = boundsY << 16;
-        this.boundsMaxX = (boundsX + boundsWidth) << 16;
-        this.boundsMaxY = (boundsY + boundsHeight) << 16;
-
-        this.bboxX0 = boundsX;
-        this.bboxY0 = boundsY;
-        this.bboxX1 = boundsX + boundsWidth;
-        this.bboxY1 = boundsY + boundsHeight;
+    private float tosubpixx(float pix_x) {
+        return pix_x * SUBPIXEL_POSITIONS_X;
+    }
+    private float tosubpixy(float pix_y) {
+        return pix_y * SUBPIXEL_POSITIONS_Y;
     }
 
-    public void moveTo(int x0, int y0) {
-        // System.out.println("Renderer: moveTo " + x0/65536.0 + " " + y0/65536.0);
+    public void moveTo(float pix_x0, float pix_y0) {
         close();
-        this.sx0 = this.x0 = x0;
-        this.sy0 = this.y0 = y0;
-        this.lastOrientation = 0;
+        this.pix_sx0 = pix_x0;
+        this.pix_sy0 = pix_y0;
+        this.y0 = tosubpixy(pix_y0);
+        this.x0 = tosubpixx(pix_x0);
     }
 
-    public void lineJoin() {
-        // System.out.println("Renderer: lineJoin");
-        // do nothing
-    }
+    public void lineJoin() { /* do nothing */ }
 
-    public void lineTo(int x1, int y1) {
-        // System.out.println("Renderer: lineTo " + x1/65536.0 + " " + y1/65536.0);
+    public void lineTo(float pix_x1, float pix_y1) {
+        float x1 = tosubpixx(pix_x1);
+        float y1 = tosubpixy(pix_y1);
 
         // Ignore horizontal lines
-        // Next line will count flip
         if (y0 == y1) {
             this.x0 = x1;
             return;
         }
 
-        int orientation = (y0 < y1) ? 1 : -1;
-        if (lastOrientation == 0) {
-            firstOrientation = orientation;
-        } else if (orientation != lastOrientation) {
-            ++flips;
-        }
-        lastOrientation = orientation;
-
-        // Bias Y by 1 ULP so endpoints never lie on a scanline
-        addEdge(x0, y0 | 0x1, x1, y1 | 0x1);
+        addEdge(x0, y0, x1, y1);
 
         this.x0 = x1;
         this.y0 = y1;
     }
 
     public void close() {
-        // System.out.println("Renderer: close");
-
-        int orientation = lastOrientation;
-        if (y0 != sy0) {
-            orientation = (y0 < sy0) ? 1 : -1;
-        }
-        if (orientation != firstOrientation) {
-            ++flips;
-        }
-        lineTo(sx0, sy0);
+        // lineTo expects its input in pixel coordinates.
+        lineTo(pix_sx0, pix_sy0);
     }
 
     public void end() {
         close();
-        // System.out.println("Renderer: end");
-        // do nothing
-    }
-
-    // Scan convert a single edge
-    private void computeCrossingsForEdge(int index,
-                                         int boundsMinY, int boundsMaxY) {
-        int iy0 = edges[index + 1];
-        int iy1 = edges[index + 3];
-
-        // Clip to valid Y range
-        int clipy0 = (iy0 > boundsMinY) ? iy0 : boundsMinY;
-        int clipy1 = (iy1 < boundsMaxY) ? iy1 : boundsMaxY;
-
-        int minY = ((clipy0 + HYSTEP) & YMASK) + HYSTEP;
-        int maxY = ((clipy1 - HYSTEP) & YMASK) + HYSTEP;
-
-        // IMPL_NOTE - If line falls outside the valid X range, could
-        // draw a vertical line instead
-
-        // Exit if no scanlines are crossed
-        if (minY > maxY) {
-            return;
-        }
-
-        // Scan convert line using a DDA approach
-
-        int ix0 = edges[index];
-        int ix1 = edges[index + 2];
-        long dx = ((long) ix1) - ix0;
-        long dy = ((long) iy1) - iy0;
-
-        // Compute first crossing point at y = minY
-        int orientation = edges[index + 4];
-        int y = minY;
-        long lx = (((long) y) - iy0)*dx/dy + ix0;
-        addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation);
-
-        // Advance y to next scanline, exit if past endpoint
-        y += YSTEP;
-        if (y > maxY) {
-            return;
-        }
-
-        // Compute xstep only if additional scanlines are crossed
-        // For each scanline, add xstep to lx and YSTEP to y and
-        // emit the new crossing
-        long xstep = ((long)YSTEP*dx)/dy;
-        for (; y <= maxY; y += YSTEP) {
-            lx += xstep;
-            addCrossing(y >> YSHIFT, (int)(lx >> XSHIFT), orientation);
-        }
-    }
-
-    private void computeBounds() {
-        rasterMinX = crossingMinX & ~SUBPIXEL_MASK_X;
-        rasterMaxX = crossingMaxX | SUBPIXEL_MASK_X;
-        rasterMinY = crossingMinY & ~SUBPIXEL_MASK_Y;
-        rasterMaxY = crossingMaxY | SUBPIXEL_MASK_Y;
-
-        // If nothing was drawn, we have:
-        // minX = Integer.MAX_VALUE and maxX = Integer.MIN_VALUE
-        // so nothing to render
-        if (rasterMinX > rasterMaxX || rasterMinY > rasterMaxY) {
-            rasterMinX = 0;
-            rasterMaxX = -1;
-            rasterMinY = 0;
-            rasterMaxY = -1;
-            return;
-        }
-
-        if (rasterMinX < boundsMinX >> XSHIFT) {
-            rasterMinX = boundsMinX >> XSHIFT;
-        }
-        if (rasterMinY < boundsMinY >> YSHIFT) {
-            rasterMinY = boundsMinY >> YSHIFT;
-        }
-        if (rasterMaxX > boundsMaxX >> XSHIFT) {
-            rasterMaxX = boundsMaxX >> XSHIFT;
-        }
-        if (rasterMaxY > boundsMaxY >> YSHIFT) {
-            rasterMaxY = boundsMaxY >> YSHIFT;
-        }
-    }
-
-    private int clamp(int x, int min, int max) {
-        if (x < min) {
-            return min;
-        } else if (x > max) {
-            return max;
-        }
-        return x;
     }
 
     private void _endRendering() {
-        if (flips == 0) {
-            bboxX0 = bboxY0 = 0;
-            bboxX1 = bboxY1 = -1;
-            return;
-        }
+        // Mask to determine the relevant bit of the crossing sum
+        // 0x1 if EVEN_ODD, all bits if NON_ZERO
+        int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0;
+
+        // add 1 to better deal with the last pixel in a pixel row.
+        int width = ((boundsMaxX - boundsMinX) >> SUBPIXEL_LG_POSITIONS_X) + 1;
+        byte[] alpha = new byte[width+1];
 
-        // Special case for filling a single rect with a flat, opaque color
-        // REMIND: This special case was not originally written to fill a
-        // cache object and called directly to a Blit - it needs some code
-        // to fill the cache instead to be useful for this usage...
-        if (false /* Does not work with cache (yet?) */ &&
-            edgeIdx == 10 &&
-            edges[0] == edges[2] &&
-            edges[1] == edges[6] &&
-            edges[3] == edges[8] &&
-            edges[5] == edges[7] &&
-            Math.abs(edges[0] - edges[5]) > MIN_QUAD_OPT_WIDTH)
-        {
+        // Now we iterate through the scanlines. We must tell emitRow the coord
+        // of the first non-transparent pixel, so we must keep accumulators for
+        // the first and last pixels of the section of the current pixel row
+        // that we will emit.
+        // We also need to accumulate pix_bbox*, but the iterator does it
+        // for us. We will just get the values from it once this loop is done
+        int pix_maxX = Integer.MIN_VALUE;
+        int pix_minX = Integer.MAX_VALUE;
 
-            int x0 = edges[0] >> XSHIFT;
-            int y0 = edges[1] >> YSHIFT;
-            int x1 = edges[5] >> XSHIFT;
-            int y1 = edges[3] >> YSHIFT;
+        int y = boundsMinY; // needs to be declared here so we emit the last row properly.
+        ScanLineItInitialize();
+        for ( ; ScanLineItHasNext(); ) {
+            int numCrossings = ScanLineItGoToNextYAndComputeCrossings();
+            y = ScanLineItCurrentY();
 
-            if (x0 > x1) {
-                int tmp = x0;
-                x0 = x1;
-                x1 = tmp;
-            }
-            if (y0 > y1) {
-                int tmp = y0;
-                y0 = y1;
-                y1 = tmp;
+            if (numCrossings > 0) {
+                int lowx = crossings[0] >> 1;
+                int highx = crossings[numCrossings - 1] >> 1;
+                int x0 = Math.max(lowx, boundsMinX);
+                int x1 = Math.min(highx, boundsMaxX);
+
+                pix_minX = Math.min(pix_minX, x0 >> SUBPIXEL_LG_POSITIONS_X);
+                pix_maxX = Math.max(pix_maxX, x1 >> SUBPIXEL_LG_POSITIONS_X);
             }
 
-            int bMinX = this.boundsMinX >> XSHIFT;
-            int bMinY = this.boundsMinY >> YSHIFT;
-            int bMaxX = this.boundsMaxX >> XSHIFT;
-            int bMaxY = this.boundsMaxY >> YSHIFT;
+            int sum = 0;
+            int prev = boundsMinX;
+            for (int i = 0; i < numCrossings; i++) {
+                int curxo = crossings[i];
+                int curx = curxo >> 1;
+                int crorientation = ((curxo & 0x1) == 0x1) ? 1 : -1;
+                if ((sum & mask) != 0) {
+                    int x0 = Math.max(prev, boundsMinX);
+                    int x1 = Math.min(curx, boundsMaxX);
+                    if (x0 < x1) {
+                        x0 -= boundsMinX; // turn x0, x1 from coords to indeces
+                        x1 -= boundsMinX; // in the alpha array.
 
-            // Clip to image bounds in supersampled coordinates
-            x0 = clamp(x0, bMinX, bMaxX);
-            x1 = clamp(x1, bMinX, bMaxX);
-            y0 = clamp(y0, bMinY, bMaxY);
-            y1 = clamp(y1, bMinY, bMaxY);
+                        int pix_x = x0 >> SUBPIXEL_LG_POSITIONS_X;
+                        int pix_xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X;
 
-            /*
-             * REMIND: Need to fill the cache here instead...
-            Blit.fillRectSrcOver(this,
-                                 imageData, imageType,
-                                 imageOffset,
-                                 imageScanlineStride, imagePixelStride,
-                                 width, height,
-                                 x0, y0, x1, y1,
-                                 cred, cgreen, cblue);
-            */
+                        if (pix_x == pix_xmaxm1) {
+                            // Start and end in same pixel
+                            alpha[pix_x] += (x1 - x0);
+                            alpha[pix_x+1] -= (x1 - x0);
+                        } else {
+                            int pix_xmax = x1 >> SUBPIXEL_LG_POSITIONS_X;
+                            alpha[pix_x] += SUBPIXEL_POSITIONS_X - (x0 & SUBPIXEL_MASK_X);
+                            alpha[pix_x+1] += (x0 & SUBPIXEL_MASK_X);
+                            alpha[pix_xmax] -= SUBPIXEL_POSITIONS_X - (x1 & SUBPIXEL_MASK_X);
+                            alpha[pix_xmax+1] -= (x1 & SUBPIXEL_MASK_X);
+                        }
+                    }
+                }
+                sum += crorientation;
+                prev = curx;
+            }
 
-            bboxX0 = x0 >> SUBPIXEL_LG_POSITIONS_X;
-            bboxY0 = y0 >> SUBPIXEL_LG_POSITIONS_Y;
-            bboxX1 = (x1 + SUBPIXEL_POSITIONS_X - 1)
-                >> SUBPIXEL_LG_POSITIONS_X;
-            bboxY1 = (y1 + SUBPIXEL_POSITIONS_Y - 1)
-                >> SUBPIXEL_LG_POSITIONS_Y;
-
-            return;
-        }
-
-        int minY = (edgeMinY > boundsMinY) ? edgeMinY : boundsMinY;
-        int maxY = (edgeMaxY < boundsMaxY) ? edgeMaxY : boundsMaxY;
-
-        // Check for empty intersection of primitive with the drawing area
-        if (minY > maxY) {
-            bboxX0 = bboxY0 = 0;
-            bboxX1 = bboxY1 = -1;
-            return;
+            if ((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) {
+                emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX);
+                pix_minX = Integer.MAX_VALUE;
+                pix_maxX = Integer.MIN_VALUE;
+            }
         }
 
-        // Compute Y extent in subpixel coordinates
-        int iminY = (minY >> YSHIFT) & ~SUBPIXEL_MASK_Y;
-        int imaxY = (maxY >> YSHIFT) | SUBPIXEL_MASK_Y;
-        int yextent = (imaxY - iminY) + 1;
-
-        // Maximum number of crossings
-        int size = flips*yextent;
-
-        int bmax = (boundsMaxY >> YSHIFT) - 1;
-        if (imaxY > bmax) {
-            imaxY = bmax;
+        // Emit final row
+        if (pix_maxX >= pix_minX) {
+            emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX);
         }
-
-        // Initialize X bounds, will be refined for each strip
-        bboxX0 = Integer.MAX_VALUE;
-        bboxX1 = Integer.MIN_VALUE;
-
-        // Set Y bounds
-        bboxY0 = iminY >> SUBPIXEL_LG_POSITIONS_Y;
-        bboxY1 = (imaxY + SUBPIXEL_POSITIONS_Y - 1) >> SUBPIXEL_LG_POSITIONS_Y;
-
-        // Compute number of rows that can be processing using
-        // a crossings table no larger than DEFAULT_CROSSINGS_SIZE.
-        // However, we must process at least one row, so we grow the table
-        // temporarily if needed.  This would require an object with a
-        // huge number of flips.
-        int rows = DEFAULT_CROSSINGS_SIZE/(flips*SUBPIXEL_POSITIONS_Y);
-        rows = Math.min(rows, yextent);
-        rows = Math.max(rows, 1);
-        for (int i = iminY; i <= imaxY; i += rows*SUBPIXEL_POSITIONS_Y) {
-            // Compute index of last scanline to be processed in this pass
-            int last = Math.min(i + rows*SUBPIXEL_POSITIONS_Y - 1, imaxY);
-            setCrossingsExtents(i, last, flips);
-
-            int bminY = i << YSHIFT;
-            int bmaxY = (last << YSHIFT) | ~YMASK;
+        pix_bboxX0 = minX >> SUBPIXEL_LG_POSITIONS_X;
+        pix_bboxX1 = maxX >> SUBPIXEL_LG_POSITIONS_X;
+        pix_bboxY0 = minY >> SUBPIXEL_LG_POSITIONS_Y;
+        pix_bboxY1 = maxY >> SUBPIXEL_LG_POSITIONS_Y;
+    }
 
-            // Process edges from the edge list
-            int maxIdx = edgeIdx;
-            for (int index = 0; index < maxIdx; index += 5) {
-                // Test y1 < min:
-                //
-                // If edge lies entirely above current strip,
-                // discard it
-                if (edges[index + 3] < bminY) {
-                    // Overwrite the edge with the last edge
-                    edgeIdx -= 5;
-                    int fidx = edgeIdx;
-                    int tidx = index;
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx++] = edges[fidx++];
-                    edges[tidx  ] = edges[fidx  ];
-
-                    maxIdx -= 5;
-                    index -= 5;
-                    continue;
-                }
-
-                // Test y0 > max:
-                //
-                // If edge lies entirely below current strip,
-                // skip it for now
-                if (edges[index + 1] > bmaxY) {
-                    continue;
-                }
-
-                computeCrossingsForEdge(index, bminY, bmaxY);
-            }
-
-            computeBounds();
-            if (rasterMaxX < rasterMinX) {
-                continue;
-            }
-
-            bboxX0 = Math.min(bboxX0,
-                              rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
-            bboxX1 = Math.max(bboxX1,
-                              (rasterMaxX + SUBPIXEL_POSITIONS_X - 1)
-                              >> SUBPIXEL_LG_POSITIONS_X);
-            renderStrip();
-        }
-
-        // Free up any unusually large scratchpad memory used by the
-        // preceding primitive
-        crossingListFinished();
-    }
 
     public void endRendering() {
         // Set up the cache to accumulate the bounding box
@@ -478,176 +472,31 @@
         _endRendering();
     }
 
-    public void getBoundingBox(int[] bbox) {
-        bbox[0] = bboxX0;
-        bbox[1] = bboxY0;
-        bbox[2] = bboxX1 - bboxX0;
-        bbox[3] = bboxY1 - bboxY0;
+    public void getBoundingBox(int[] pix_bbox) {
+        pix_bbox[0] = pix_bboxX0;
+        pix_bbox[1] = pix_bboxY0;
+        pix_bbox[2] = pix_bboxX1 - pix_bboxX0;
+        pix_bbox[3] = pix_bboxY1 - pix_bboxY0;
     }
 
-    private void renderStrip() {
-        // Grow rowAA according to the raster width
-        int width = (rasterMaxX - rasterMinX + 1) >> SUBPIXEL_LG_POSITIONS_X;
-        alphaWidth = width;
-
-        // Allocate one extra entry in rowAA to avoid a conditional in
-        // the rendering loop
-        int bufLen = width + 1;
-        if (this.rowAA == null || this.rowAA.length < bufLen) {
-            this.rowAA = new byte[bufLen];
-        }
-
-        // Mask to determine the relevant bit of the crossing sum
-        // 0x1 if EVEN_ODD, all bits if NON_ZERO
-        int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0;
-
-        int y = 0;
-        int prevY = rasterMinY - 1;
-
-        int minX = Integer.MAX_VALUE;
-        int maxX = Integer.MIN_VALUE;
-
-        iterateCrossings();
-        while (hasMoreCrossingRows()) {
-            y = crossingY;
-
-            // Emit any skipped rows
-            for (int j = prevY + 1; j < y; j++) {
-                if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
-                    (j == rasterMaxY)) {
-                    emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, 0, -1);
-                }
-            }
-            prevY = y;
-
-            if (crossingRowIndex < crossingRowCount) {
-                int lx = crossings[crossingRowOffset + crossingRowIndex];
-                lx >>= 1;
-                int hx = crossings[crossingRowOffset + crossingRowCount - 1];
-                hx >>= 1;
-                int x0 = lx > rasterMinX ? lx : rasterMinX;
-                int x1 = hx < rasterMaxX ? hx : rasterMaxX;
-                x0 -= rasterMinX;
-                x1 -= rasterMinX;
-
-                minX = Math.min(minX, x0 >> SUBPIXEL_LG_POSITIONS_X);
-                maxX = Math.max(maxX, x1 >> SUBPIXEL_LG_POSITIONS_X);
-            }
-
-            int sum = 0;
-            int prev = rasterMinX;
-            while (crossingRowIndex < crossingRowCount) {
-                int crxo = crossings[crossingRowOffset + crossingRowIndex];
-                crossingRowIndex++;
-
-                int crx = crxo >> 1;
-                int crorientation = ((crxo & 0x1) == 0x1) ? 1 : -1;
-
-                if ((sum & mask) != 0) {
-                    // Clip to active X range, if x1 < x0 loop will
-                    // have no effect
-                    int x0 = prev > rasterMinX ? prev : rasterMinX;
-                    int x1 =  crx < rasterMaxX ?  crx : rasterMaxX;
-
-                    // Empty spans
-                    if (x1 > x0) {
-                        x0 -= rasterMinX;
-                        x1 -= rasterMinX;
-
-                        // Accumulate alpha, equivalent to:
-                        //   for (int x = x0; x < x1; x++) {
-                        //       ++rowAA[x >> SUBPIXEL_LG_POSITIONS_X];
-                        //   }
-                        //
-                        // In the middle of the span, we can update a full
-                        // pixel at a time (i.e., SUBPIXEL_POSITIONS_X
-                        // subpixels)
-
-                        int x = x0 >> SUBPIXEL_LG_POSITIONS_X;
-                        int xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X;
-                        if (x == xmaxm1) {
-                            // Start and end in same pixel
-                            rowAA[x] += x1 - x0;
-                        } else {
-                            // Start and end in different pixels
-                            rowAA[x++] += SUBPIXEL_POSITIONS_X -
-                                (x0 & SUBPIXEL_MASK_X);
-                            int xmax = x1 >> SUBPIXEL_LG_POSITIONS_X;
-                            while (x < xmax) {
-                                rowAA[x++] += SUBPIXEL_POSITIONS_X;
-                            }
-                            // Note - at this point it is possible that
-                            // x == width, which implies that
-                            // x1 & SUBPIXEL_MASK_X == 0.  We allocate
-                            // one extra entry in rowAA so this
-                            // assignment will be harmless.  The alternative
-                            // is an extra conditional here, or some other
-                            // scheme to deal with the last pixel better.
-                            rowAA[x] += x1 & SUBPIXEL_MASK_X;
-                        }
-                    }
-                }
-                sum += crorientation;
-                prev = crx;
-            }
-
-            // Every SUBPIXEL_POSITIONS rows, output an antialiased row
-            if (((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
-                (y == rasterMaxY)) {
-                emitRow(y >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX);
-                minX = Integer.MAX_VALUE;
-                maxX = Integer.MIN_VALUE;
-            }
-        }
-
-        // Emit final row
-        for (int j = prevY + 1; j <= rasterMaxY; j++) {
-            if (((j & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) ||
-                (j == rasterMaxY)) {
-                emitRow(j >> SUBPIXEL_LG_POSITIONS_Y, minX, maxX);
-                minX = Integer.MAX_VALUE;
-                maxX = Integer.MIN_VALUE;
-            }
-        }
-    }
-
-    private void clearAlpha(byte[] alpha,
-                            int width,
-                            int minX, int maxX) {
-        if (maxX >= minX) {
-            int w = maxX - minX + 1;
-            if (w + minX > width) {
-                w = width - minX;
-            }
-
-            int aidx = minX;
-            for (int i = 0; i < w; i++, aidx++) {
-                alpha[aidx] = (byte)0;
-            }
-        }
-    }
-
-    private void emitRow(int y, int minX, int maxX) {
+    private void emitRow(byte[] alphaRow, int pix_y, int pix_from, int pix_to) {
         // Copy rowAA data into the cache if one is present
         if (cache != null) {
-            if (maxX >= minX) {
-                int x0 = minX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
-                int x1 = maxX + (rasterMinX >> SUBPIXEL_LG_POSITIONS_X);
+            if (pix_to >= pix_from) {
+                cache.startRow(pix_y, pix_from, pix_to);
 
-                cache.startRow(y, x0, x1);
-                int srcIdx = minX;
+                // Perform run-length encoding and store results in the cache
+                int from = pix_from - (boundsMinX >> SUBPIXEL_LG_POSITIONS_X);
+                int to = pix_to - (boundsMinX >> SUBPIXEL_LG_POSITIONS_X);
 
-                // Perform run-length encoding
-                // and store results in the cache
-                byte startVal = rowAA[srcIdx++];
                 int runLen = 1;
-                while (srcIdx <= maxX) {
-                    byte nextVal = rowAA[srcIdx++];
+                byte startVal = alphaRow[from];
+                for (int i = from + 1; i <= to; i++) {
+                    byte nextVal = (byte)(startVal + alphaRow[i]);
                     if (nextVal == startVal && runLen < 255) {
-                        ++runLen;
+                        runLen++;
                     } else {
                         cache.addRLERun(startVal, runLen);
-
                         runLen = 1;
                         startVal = nextVal;
                     }
@@ -656,190 +505,6 @@
                 cache.addRLERun((byte)0, 0);
             }
         }
-
-        clearAlpha(rowAA,
-                   alphaWidth,
-                   minX, maxX);
-    }
-
-    public void setCache(PiscesCache cache) {
-        this.cache = cache;
-    }
-
-    // Edge list data
-
-    private int[] edges = new int[5*INITIAL_EDGES];
-    private int edgeIdx = 0;
-    private int edgeMinY = Integer.MAX_VALUE;
-    private int edgeMaxY = Integer.MIN_VALUE;
-
-    private void addEdge(int x0, int y0, int x1, int y1) {
-        int newLen = edgeIdx + 5;
-        if (edges.length < newLen) {
-            int[] tmp = new int[Math.max(11*edges.length/10, newLen)];
-            System.arraycopy(edges, 0, tmp, 0, edgeIdx);
-            this.edges = tmp;
-        }
-
-        int orientation = 1;
-        if (y0 > y1) {
-            int tmp = y0;
-            y0 = y1;
-            y1 = tmp;
-
-            orientation = -1;
-        }
-
-        // Skip edges that don't cross a subsampled scanline
-        int eminY = ((y0 + HYSTEP) & YMASK);
-        int emaxY = ((y1 - HYSTEP) & YMASK);
-        if (eminY > emaxY) {
-            return;
-        }
-
-        if (orientation == -1) {
-            int tmp = x0;
-            x0 = x1;
-            x1 = tmp;
-        }
-
-        edges[edgeIdx++] = x0;
-        edges[edgeIdx++] = y0;
-        edges[edgeIdx++] = x1;
-        edges[edgeIdx++] = y1;
-        edges[edgeIdx++] = orientation;
-
-        // Update Y bounds of primitive
-        if (y0 < edgeMinY) {
-            edgeMinY = y0;
-        }
-        if (y1 > edgeMaxY) {
-            edgeMaxY = y1;
-        }
-    }
-
-    private void resetEdges() {
-        this.edgeIdx = 0;
-        this.edgeMinY = Integer.MAX_VALUE;
-        this.edgeMaxY = Integer.MIN_VALUE;
-    }
-
-    // Crossing list data
-
-    private int[] crossingIndices;
-    private int[] crossings;
-    private int crossingMinY;
-    private int crossingMaxY;
-    private int crossingMinX = Integer.MAX_VALUE;
-    private int crossingMaxX = Integer.MIN_VALUE;
-    private int crossingMaxXEntries;
-    private int numCrossings = 0;
-    private boolean crossingsSorted = false;
-
-    private int crossingY;
-    private int crossingRowCount;
-    private int crossingRowOffset;
-    private int crossingRowIndex;
-
-    private void setCrossingsExtents(int minY, int maxY, int maxXEntries) {
-        int yextent = maxY - minY + 1;
-
-        // Grow indices array as needed
-        if (crossingIndices == null || crossingIndices.length < yextent) {
-            this.crossingIndices =
-                new int[Math.max(yextent, DEFAULT_INDICES_SIZE)];
-        }
-        // Grow crossings array as needed
-        if (crossings == null || crossings.length < yextent*maxXEntries) {
-            this.crossings = new int[Math.max(yextent*maxXEntries,
-                                              DEFAULT_CROSSINGS_SIZE)];
-        }
-        this.crossingMinY = minY;
-        this.crossingMaxY = maxY;
-        this.crossingMaxXEntries = maxXEntries;
-        resetCrossings();
-    }
-
-    private void resetCrossings() {
-        int yextent = crossingMaxY - crossingMinY + 1;
-        int start = 0;
-        for (int i = 0; i < yextent; i++) {
-            crossingIndices[i] = start;
-            start += crossingMaxXEntries;
-        }
-        crossingMinX = Integer.MAX_VALUE;
-        crossingMaxX = Integer.MIN_VALUE;
-        numCrossings = 0;
-        crossingsSorted = false;
-    }
-
-    // Free sorting arrays if larger than maximum size
-    private void crossingListFinished() {
-        if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) {
-            crossings = new int[DEFAULT_CROSSINGS_SIZE];
-        }
-        if (crossingIndices != null &&
-            crossingIndices.length > DEFAULT_INDICES_SIZE)
-        {
-            crossingIndices = new int[DEFAULT_INDICES_SIZE];
-        }
-    }
-
-    private void sortCrossings(int[] x, int off, int len) {
-        for (int i = off + 1; i < off + len; i++) {
-            int j = i;
-            int xj = x[j];
-            int xjm1;
-
-            while (j > off && (xjm1 = x[j - 1]) > xj) {
-                x[j] = xjm1;
-                x[j - 1] = xj;
-                j--;
-            }
-        }
-    }
-
-    private void sortCrossings() {
-        int start = 0;
-        for (int i = 0; i <= crossingMaxY - crossingMinY; i++) {
-            sortCrossings(crossings, start, crossingIndices[i] - start);
-            start += crossingMaxXEntries;
-        }
-    }
-
-    private void addCrossing(int y, int x, int orientation) {
-        if (x < crossingMinX) {
-            crossingMinX = x;
-        }
-        if (x > crossingMaxX) {
-            crossingMaxX = x;
-        }
-
-        int index = crossingIndices[y - crossingMinY]++;
-        x <<= 1;
-        crossings[index] = (orientation == 1) ? (x | 0x1) : x;
-
-        ++numCrossings;
-    }
-
-    private void iterateCrossings() {
-        if (!crossingsSorted) {
-            sortCrossings();
-            crossingsSorted = true;
-        }
-        crossingY = crossingMinY - 1;
-        crossingRowOffset = -crossingMaxXEntries;
-    }
-
-    private boolean hasMoreCrossingRows() {
-        if (++crossingY <= crossingMaxY) {
-            crossingRowOffset += crossingMaxXEntries;
-            int y = crossingY - crossingMinY;
-            crossingRowCount = crossingIndices[y] - y*crossingMaxXEntries;
-            crossingRowIndex = 0;
-            return true;
-        } else {
-            return false;
-        }
+        java.util.Arrays.fill(alphaRow, (byte)0);
     }
 }
--- a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java	Thu Sep 02 12:17:21 2010 -0700
@@ -25,7 +25,7 @@
 
 package sun.java2d.pisces;
 
-public class Stroker extends LineSink {
+public class Stroker implements LineSink {
 
     private static final int MOVE_TO = 0;
     private static final int LINE_TO = 1;
@@ -61,19 +61,15 @@
      */
     public static final int CAP_SQUARE = 2;
 
-    LineSink output;
+    private final LineSink output;
 
-    int lineWidth;
-    int capStyle;
-    int joinStyle;
-    int miterLimit;
+    private final int capStyle;
+    private final int joinStyle;
 
-    Transform4 transform;
-    int m00, m01;
-    int m10, m11;
+    private final float m00, m01, m10, m11, det;
 
-    int lineWidth2;
-    long scaledLineWidth2;
+    private final float lineWidth2;
+    private final float scaledLineWidth2;
 
     // For any pen offset (pen_dx, pen_dy) that does not depend on
     // the line orientation, the pen should be transformed so that:
@@ -88,143 +84,86 @@
     //
     // pen_dx'(r, theta) = r*(m00*cos(theta) + m01*sin(theta))
     // pen_dy'(r, theta) = r*(m10*cos(theta) + m11*sin(theta))
-    int numPenSegments;
-    int[] pen_dx;
-    int[] pen_dy;
-    boolean[] penIncluded;
-    int[] join;
+    private int numPenSegments;
+    private final float[] pen_dx;
+    private final float[] pen_dy;
+    private boolean[] penIncluded;
+    private final float[] join;
 
-    int[] offset = new int[2];
-    int[] reverse = new int[100];
-    int[] miter = new int[2];
-    long miterLimitSq;
+    private final float[] offset = new float[2];
+    private float[] reverse = new float[100];
+    private final float[] miter = new float[2];
+    private final float miterLimitSq;
 
-    int prev;
-    int rindex;
-    boolean started;
-    boolean lineToOrigin;
-    boolean joinToOrigin;
-
-    int sx0, sy0, sx1, sy1, x0, y0, x1, y1;
-    int mx0, my0, mx1, my1, omx, omy;
-    int lx0, ly0, lx1, ly1, lx0p, ly0p, px0, py0;
+    private int prev;
+    private int rindex;
+    private boolean started;
+    private boolean lineToOrigin;
+    private boolean joinToOrigin;
 
-    double m00_2_m01_2;
-    double m10_2_m11_2;
-    double m00_m10_m01_m11;
+    private float sx0, sy0, sx1, sy1, x0, y0, px0, py0;
+    private float mx0, my0, omx, omy;
 
-    /**
-     * Empty constructor.  <code>setOutput</code> and
-     * <code>setParameters</code> must be called prior to calling any
-     * other methods.
-     */
-    public Stroker() {}
+    private float m00_2_m01_2;
+    private float m10_2_m11_2;
+    private float m00_m10_m01_m11;
 
     /**
      * Constructs a <code>Stroker</code>.
      *
      * @param output an output <code>LineSink</code>.
-     * @param lineWidth the desired line width in pixels, in S15.16
-     * format.
+     * @param lineWidth the desired line width in pixels
      * @param capStyle the desired end cap style, one of
      * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or
      * <code>CAP_SQUARE</code>.
      * @param joinStyle the desired line join style, one of
      * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or
      * <code>JOIN_BEVEL</code>.
-     * @param miterLimit the desired miter limit, in S15.16 format.
+     * @param miterLimit the desired miter limit
      * @param transform a <code>Transform4</code> object indicating
      * the transform that has been previously applied to all incoming
      * coordinates.  This is required in order to produce consistently
      * shaped end caps and joins.
      */
     public Stroker(LineSink output,
-                   int lineWidth,
+                   float lineWidth,
                    int capStyle,
                    int joinStyle,
-                   int miterLimit,
-                   Transform4 transform) {
-        setOutput(output);
-        setParameters(lineWidth, capStyle, joinStyle, miterLimit, transform);
-    }
-
-    /**
-     * Sets the output <code>LineSink</code> of this
-     * <code>Stroker</code>.
-     *
-     * @param output an output <code>LineSink</code>.
-     */
-    public void setOutput(LineSink output) {
+                   float miterLimit,
+                   float m00, float m01, float m10, float m11) {
         this.output = output;
-    }
 
-    /**
-     * Sets the parameters of this <code>Stroker</code>.
-     * @param lineWidth the desired line width in pixels, in S15.16
-     * format.
-     * @param capStyle the desired end cap style, one of
-     * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or
-     * <code>CAP_SQUARE</code>.
-     * @param joinStyle the desired line join style, one of
-     * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or
-     * <code>JOIN_BEVEL</code>.
-     * @param miterLimit the desired miter limit, in S15.16 format.
-     * @param transform a <code>Transform4</code> object indicating
-     * the transform that has been previously applied to all incoming
-     * coordinates.  This is required in order to produce consistently
-     * shaped end caps and joins.
-     */
-    public void setParameters(int lineWidth,
-                              int capStyle,
-                              int joinStyle,
-                              int miterLimit,
-                              Transform4 transform) {
-        this.lineWidth = lineWidth;
-        this.lineWidth2 = lineWidth >> 1;
-        this.scaledLineWidth2 = ((long)transform.m00*lineWidth2) >> 16;
+        this.lineWidth2 = lineWidth / 2;
+        this.scaledLineWidth2 = m00 * lineWidth2;
         this.capStyle = capStyle;
         this.joinStyle = joinStyle;
-        this.miterLimit = miterLimit;
 
-        this.transform = transform;
-        this.m00 = transform.m00;
-        this.m01 = transform.m01;
-        this.m10 = transform.m10;
-        this.m11 = transform.m11;
-
-        this.m00_2_m01_2 = (double)m00*m00 + (double)m01*m01;
-        this.m10_2_m11_2 = (double)m10*m10 + (double)m11*m11;
-        this.m00_m10_m01_m11 = (double)m00*m10 + (double)m01*m11;
+        m00_2_m01_2 = m00*m00 + m01*m01;
+        m10_2_m11_2 = m10*m10 + m11*m11;
+        m00_m10_m01_m11 = m00*m10 + m01*m11;
 
-        double dm00 = m00/65536.0;
-        double dm01 = m01/65536.0;
-        double dm10 = m10/65536.0;
-        double dm11 = m11/65536.0;
-        double determinant = dm00*dm11 - dm01*dm10;
+        this.m00 = m00;
+        this.m01 = m01;
+        this.m10 = m10;
+        this.m11 = m11;
+        det = m00*m11 - m01*m10;
 
-        if (joinStyle == JOIN_MITER) {
-            double limit =
-                (miterLimit/65536.0)*(lineWidth2/65536.0)*determinant;
-            double limitSq = limit*limit;
-            this.miterLimitSq = (long)(limitSq*65536.0*65536.0);
-        }
+        float limit = miterLimit * lineWidth2 * det;
+        this.miterLimitSq = limit*limit;
 
-        this.numPenSegments = (int)(3.14159f*lineWidth/65536.0f);
-        if (pen_dx == null || pen_dx.length < numPenSegments) {
-            this.pen_dx = new int[numPenSegments];
-            this.pen_dy = new int[numPenSegments];
-            this.penIncluded = new boolean[numPenSegments];
-            this.join = new int[2*numPenSegments];
-        }
+        this.numPenSegments = (int)(3.14159f * lineWidth);
+        this.pen_dx = new float[numPenSegments];
+        this.pen_dy = new float[numPenSegments];
+        this.penIncluded = new boolean[numPenSegments];
+        this.join = new float[2*numPenSegments];
 
         for (int i = 0; i < numPenSegments; i++) {
-            double r = lineWidth/2.0;
-            double theta = (double)i*2.0*Math.PI/numPenSegments;
+            double theta = (i * 2.0 * Math.PI)/numPenSegments;
 
             double cos = Math.cos(theta);
             double sin = Math.sin(theta);
-            pen_dx[i] = (int)(r*(dm00*cos + dm01*sin));
-            pen_dy[i] = (int)(r*(dm10*cos + dm11*sin));
+            pen_dx[i] = (float)(lineWidth2 * (m00*cos + m01*sin));
+            pen_dy[i] = (float)(lineWidth2 * (m10*cos + m11*sin));
         }
 
         prev = CLOSE;
@@ -233,32 +172,31 @@
         lineToOrigin = false;
     }
 
-    private void computeOffset(int x0, int y0, int x1, int y1, int[] m) {
-        long lx = (long)x1 - (long)x0;
-        long ly = (long)y1 - (long)y0;
+    private void computeOffset(float x0, float y0,
+                               float x1, float y1, float[] m) {
+        float lx = x1 - x0;
+        float ly = y1 - y0;
 
-        int dx, dy;
+        float dx, dy;
         if (m00 > 0 && m00 == m11 && m01 == 0 & m10 == 0) {
-            long ilen = PiscesMath.hypot(lx, ly);
+            float ilen = (float)Math.hypot(lx, ly);
             if (ilen == 0) {
                 dx = dy = 0;
             } else {
-                dx = (int)( (ly*scaledLineWidth2)/ilen);
-                dy = (int)(-(lx*scaledLineWidth2)/ilen);
+                dx = (ly * scaledLineWidth2)/ilen;
+                dy = -(lx * scaledLineWidth2)/ilen;
             }
         } else {
-            double dlx = x1 - x0;
-            double dly = y1 - y0;
-            double det = (double)m00*m11 - (double)m01*m10;
             int sdet = (det > 0) ? 1 : -1;
-            double a = dly*m00 - dlx*m10;
-            double b = dly*m01 - dlx*m11;
-            double dh = PiscesMath.hypot(a, b);
-            double div = sdet*lineWidth2/(65536.0*dh);
-            double ddx = dly*m00_2_m01_2 - dlx*m00_m10_m01_m11;
-            double ddy = dly*m00_m10_m01_m11 - dlx*m10_2_m11_2;
-            dx = (int)(ddx*div);
-            dy = (int)(ddy*div);
+            float a = ly * m00 - lx * m10;
+            float b = ly * m01 - lx * m11;
+            float dh = (float)Math.hypot(a, b);
+            float div = sdet * lineWidth2/dh;
+
+            float ddx = ly * m00_2_m01_2 - lx * m00_m10_m01_m11;
+            float ddy = ly * m00_m10_m01_m11 - lx * m10_2_m11_2;
+            dx = ddx*div;
+            dy = ddy*div;
         }
 
         m[0] = dx;
@@ -267,58 +205,43 @@
 
     private void ensureCapacity(int newrindex) {
         if (reverse.length < newrindex) {
-            int[] tmp = new int[Math.max(newrindex, 6*reverse.length/5)];
-            System.arraycopy(reverse, 0, tmp, 0, rindex);
-            this.reverse = tmp;
+            reverse = java.util.Arrays.copyOf(reverse, 6*reverse.length/5);
         }
     }
 
-    private boolean isCCW(int x0, int y0,
-                          int x1, int y1,
-                          int x2, int y2) {
-        int dx0 = x1 - x0;
-        int dy0 = y1 - y0;
-        int dx1 = x2 - x1;
-        int dy1 = y2 - y1;
-        return (long)dx0*dy1 < (long)dy0*dx1;
+    private boolean isCCW(float x0, float y0,
+                          float x1, float y1,
+                          float x2, float y2) {
+        return (x1 - x0) * (y2 - y1) < (y1 - y0) * (x2 - x1);
     }
 
-    private boolean side(int x, int y, int x0, int y0, int x1, int y1) {
-        long lx = x;
-        long ly = y;
-        long lx0 = x0;
-        long ly0 = y0;
-        long lx1 = x1;
-        long ly1 = y1;
-
-        return (ly0 - ly1)*lx + (lx1 - lx0)*ly + (lx0*ly1 - lx1*ly0) > 0;
+    private boolean side(float x,  float y,
+                         float x0, float y0,
+                         float x1, float y1) {
+        return (y0 - y1)*x + (x1 - x0)*y + (x0*y1 - x1*y0) > 0;
     }
 
-    private int computeRoundJoin(int cx, int cy,
-                                 int xa, int ya,
-                                 int xb, int yb,
+    private int computeRoundJoin(float cx, float cy,
+                                 float xa, float ya,
+                                 float xb, float yb,
                                  int side,
                                  boolean flip,
-                                 int[] join) {
-        int px, py;
+                                 float[] join) {
+        float px, py;
         int ncoords = 0;
 
         boolean centerSide;
         if (side == 0) {
             centerSide = side(cx, cy, xa, ya, xb, yb);
         } else {
-            centerSide = (side == 1) ? true : false;
+            centerSide = (side == 1);
         }
         for (int i = 0; i < numPenSegments; i++) {
             px = cx + pen_dx[i];
             py = cy + pen_dy[i];
 
             boolean penSide = side(px, py, xa, ya, xb, yb);
-            if (penSide != centerSide) {
-                penIncluded[i] = true;
-            } else {
-                penIncluded[i] = false;
-            }
+            penIncluded[i] = (penSide != centerSide);
         }
 
         int start = -1, end = -1;
@@ -338,10 +261,10 @@
         }
 
         if (start != -1 && end != -1) {
-            long dxa = cx + pen_dx[start] - xa;
-            long dya = cy + pen_dy[start] - ya;
-            long dxb = cx + pen_dx[start] - xb;
-            long dyb = cy + pen_dy[start] - yb;
+            float dxa = cx + pen_dx[start] - xa;
+            float dya = cy + pen_dy[start] - ya;
+            float dxb = cx + pen_dx[start] - xb;
+            float dyb = cy + pen_dy[start] - yb;
 
             boolean rev = (dxa*dxa + dya*dya > dxb*dxb + dyb*dyb);
             int i = rev ? end : start;
@@ -362,22 +285,25 @@
         return ncoords/2;
     }
 
-    private static final long ROUND_JOIN_THRESHOLD = 1000L;
-    private static final long ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000L;
+    // pisces used to use fixed point arithmetic with 16 decimal digits. I
+    // didn't want to change the values of the constants below when I converted
+    // it to floating point, so that's why the divisions by 2^16 are there.
+    private static final float ROUND_JOIN_THRESHOLD = 1000/65536f;
+    private static final float ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000/65536f;
 
-    private void drawRoundJoin(int x, int y,
-                               int omx, int omy, int mx, int my,
+    private void drawRoundJoin(float x, float y,
+                               float omx, float omy, float mx, float my,
                                int side,
                                boolean flip,
                                boolean rev,
-                               long threshold) {
+                               float threshold) {
         if ((omx == 0 && omy == 0) || (mx == 0 && my == 0)) {
             return;
         }
 
-        long domx = (long)omx - mx;
-        long domy = (long)omy - my;
-        long len = domx*domx + domy*domy;
+        float domx = omx - mx;
+        float domy = omy - my;
+        float len = domx*domx + domy*domy;
         if (len < threshold) {
             return;
         }
@@ -389,10 +315,10 @@
             my = -my;
         }
 
-        int bx0 = x + omx;
-        int by0 = y + omy;
-        int bx1 = x + mx;
-        int by1 = y + my;
+        float bx0 = x + omx;
+        float by0 = y + omy;
+        float bx1 = x + mx;
+        float by1 = y + my;
 
         int npoints = computeRoundJoin(x, y,
                                        bx0, by0, bx1, by1, side, flip,
@@ -404,40 +330,30 @@
 
     // Return the intersection point of the lines (ix0, iy0) -> (ix1, iy1)
     // and (ix0p, iy0p) -> (ix1p, iy1p) in m[0] and m[1]
-    private void computeMiter(int ix0, int iy0, int ix1, int iy1,
-                              int ix0p, int iy0p, int ix1p, int iy1p,
-                              int[] m) {
-        long x0 = ix0;
-        long y0 = iy0;
-        long x1 = ix1;
-        long y1 = iy1;
+    private void computeMiter(float x0, float y0, float x1, float y1,
+                              float x0p, float y0p, float x1p, float y1p,
+                              float[] m) {
+        float x10 = x1 - x0;
+        float y10 = y1 - y0;
+        float x10p = x1p - x0p;
+        float y10p = y1p - y0p;
 
-        long x0p = ix0p;
-        long y0p = iy0p;
-        long x1p = ix1p;
-        long y1p = iy1p;
-
-        long x10 = x1 - x0;
-        long y10 = y1 - y0;
-        long x10p = x1p - x0p;
-        long y10p = y1p - y0p;
-
-        long den = (x10*y10p - x10p*y10) >> 16;
+        float den = x10*y10p - x10p*y10;
         if (den == 0) {
-            m[0] = ix0;
-            m[1] = iy0;
+            m[0] = x0;
+            m[1] = y0;
             return;
         }
 
-        long t = (x1p*(y0 - y0p) - x0*y10p + x0p*(y1p - y0)) >> 16;
-        m[0] = (int)(x0 + (t*x10)/den);
-        m[1] = (int)(y0 + (t*y10)/den);
+        float t = x1p*(y0 - y0p) - x0*y10p + x0p*(y1p - y0);
+        m[0] = x0 + (t*x10)/den;
+        m[1] = y0 + (t*y10)/den;
     }
 
-    private void drawMiter(int px0, int py0,
-                           int x0, int y0,
-                           int x1, int y1,
-                           int omx, int omy, int mx, int my,
+    private void drawMiter(float px0, float py0,
+                           float x0, float y0,
+                           float x1, float y1,
+                           float omx, float omy, float mx, float my,
                            boolean rev) {
         if (mx == omx && my == omy) {
             return;
@@ -461,11 +377,11 @@
                      miter);
 
         // Compute miter length in untransformed coordinates
-        long dx = (long)miter[0] - x0;
-        long dy = (long)miter[1] - y0;
-        long a = (dy*m00 - dx*m10) >> 16;
-        long b = (dy*m01 - dx*m11) >> 16;
-        long lenSq = a*a + b*b;
+        float dx = miter[0] - x0;
+        float dy = miter[1] - y0;
+        float a = dy*m00 - dx*m10;
+        float b = dy*m01 - dx*m11;
+        float lenSq = a*a + b*b;
 
         if (lenSq < miterLimitSq) {
             emitLineTo(miter[0], miter[1], rev);
@@ -473,7 +389,7 @@
     }
 
 
-    public void moveTo(int x0, int y0) {
+    public void moveTo(float x0, float y0) {
         // System.out.println("Stroker.moveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
 
         if (lineToOrigin) {
@@ -501,7 +417,7 @@
         this.joinSegment = true;
     }
 
-    public void lineTo(int x1, int y1) {
+    public void lineTo(float x1, float y1) {
         // System.out.println("Stroker.lineTo(" + x1/65536.0 + ", " + y1/65536.0 + ")");
 
         if (lineToOrigin) {
@@ -526,10 +442,10 @@
         joinSegment = false;
     }
 
-    private void lineToImpl(int x1, int y1, boolean joinSegment) {
+    private void lineToImpl(float x1, float y1, boolean joinSegment) {
         computeOffset(x0, y0, x1, y1, offset);
-        int mx = offset[0];
-        int my = offset[1];
+        float mx = offset[0];
+        float my = offset[1];
 
         if (!started) {
             emitMoveTo(x0 + mx, y0 + my);
@@ -567,10 +483,6 @@
         emitLineTo(x0 - mx, y0 - my, true);
         emitLineTo(x1 - mx, y1 - my, true);
 
-        lx0 = x1 + mx; ly0 = y1 + my;
-        lx0p = x1 - mx; ly0p = y1 - my;
-        lx1 = x1; ly1 = y1;
-
         this.omx = mx;
         this.omy = my;
         this.px0 = x0;
@@ -594,8 +506,8 @@
         }
 
         computeOffset(x0, y0, sx0, sy0, offset);
-        int mx = offset[0];
-        int my = offset[1];
+        float mx = offset[0];
+        float my = offset[1];
 
         // Draw penultimate join
         boolean ccw = isCCW(px0, py0, x0, y0, sx0, sy0);
@@ -678,12 +590,10 @@
         this.prev = MOVE_TO;
     }
 
-    long lineLength(long ldx, long ldy) {
-        long ldet = ((long)m00*m11 - (long)m01*m10) >> 16;
-        long la = ((long)ldy*m00 - (long)ldx*m10)/ldet;
-        long lb = ((long)ldy*m01 - (long)ldx*m11)/ldet;
-        long llen = (int)PiscesMath.hypot(la, lb);
-        return llen;
+    double userSpaceLineLength(double dx, double dy) {
+        double a = (dy*m00 - dx*m10)/det;
+        double b = (dy*m01 - dx*m11)/det;
+        return Math.hypot(a, b);
     }
 
     private void finish() {
@@ -692,13 +602,13 @@
                           omx, omy, -omx, -omy, 1, false, false,
                           ROUND_JOIN_THRESHOLD);
         } else if (capStyle == CAP_SQUARE) {
-            long ldx = (long)(px0 - x0);
-            long ldy = (long)(py0 - y0);
-            long llen = lineLength(ldx, ldy);
-            long s = (long)lineWidth2*65536/llen;
+            float dx = px0 - x0;
+            float dy = py0 - y0;
+            float len = (float)userSpaceLineLength(dx, dy);
+            float s = lineWidth2/len;
 
-            int capx = x0 - (int)(ldx*s >> 16);
-            int capy = y0 - (int)(ldy*s >> 16);
+            float capx = x0 - dx*s;
+            float capy = y0 - dy*s;
 
             emitLineTo(capx + omx, capy + omy);
             emitLineTo(capx - omx, capy - omy);
@@ -714,13 +624,13 @@
                           -mx0, -my0, mx0, my0, 1, false, false,
                           ROUND_JOIN_THRESHOLD);
         } else if (capStyle == CAP_SQUARE) {
-            long ldx = (long)(sx1 - sx0);
-            long ldy = (long)(sy1 - sy0);
-            long llen = lineLength(ldx, ldy);
-            long s = (long)lineWidth2*65536/llen;
+            float dx = sx1 - sx0;
+            float dy = sy1 - sy0;
+            float len = (float)userSpaceLineLength(dx, dy);
+            float s = lineWidth2/len;
 
-            int capx = sx0 - (int)(ldx*s >> 16);
-            int capy = sy0 - (int)(ldy*s >> 16);
+            float capx = sx0 - dx*s;
+            float capy = sy0 - dy*s;
 
             emitLineTo(capx - mx0, capy - my0);
             emitLineTo(capx + mx0, capy + my0);
@@ -730,17 +640,17 @@
         this.joinSegment = false;
     }
 
-    private void emitMoveTo(int x0, int y0) {
+    private void emitMoveTo(float x0, float y0) {
         // System.out.println("Stroker.emitMoveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
         output.moveTo(x0, y0);
     }
 
-    private void emitLineTo(int x1, int y1) {
+    private void emitLineTo(float x1, float y1) {
         // System.out.println("Stroker.emitLineTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
         output.lineTo(x1, y1);
     }
 
-    private void emitLineTo(int x1, int y1, boolean rev) {
+    private void emitLineTo(float x1, float y1, boolean rev) {
         if (rev) {
             ensureCapacity(rindex + 2);
             reverse[rindex++] = x1;
@@ -755,3 +665,4 @@
         output.close();
     }
 }
+
--- a/jdk/src/share/classes/sun/java2d/pisces/Transform4.java	Tue Aug 31 15:05:09 2010 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.java2d.pisces;
-
-public class Transform4 {
-
-    public int m00, m01, m10, m11;
-//     double det; // det*65536
-
-    public Transform4() {
-        this(1 << 16, 0, 0, 1 << 16);
-    }
-
-    public Transform4(int m00, int m01,
-                      int m10, int m11) {
-        this.m00 = m00;
-        this.m01 = m01;
-        this.m10 = m10;
-        this.m11 = m11;
-
-//         this.det = (double)m00*m11 - (double)m01*m10;
-    }
-
-//     public Transform4 createInverse() {
-//         double dm00 = m00/65536.0;
-//         double dm01 = m01/65536.0;
-//         double dm10 = m10/65536.0;
-//         double dm11 = m11/65536.0;
-
-//         double invdet = 65536.0/(dm00*dm11 - dm01*dm10);
-
-//         int im00 = (int)( dm11*invdet);
-//         int im01 = (int)(-dm01*invdet);
-//         int im10 = (int)(-dm10*invdet);
-//         int im11 = (int)( dm00*invdet);
-
-//         return new Transform4(im00, im01, im10, im11);
-//     }
-
-//     public void transform(int[] point) {
-//     }
-
-//     /**
-//      * Returns the length of the line segment obtained by inverse
-//      * transforming the points <code>(x0, y0)</code> and <code>(x1,
-//      * y1)</code>.
-//      */
-//     public int getTransformedLength(int x0, int x1, int y0, int y1) {
-//         int lx = x1 - x0;
-//         int ly = y1 - y0;
-
-//         double a = (double)m00*ly - (double)m10*lx;
-//         double b = (double)m01*ly - (double)m11*lx;
-//         double len = PiscesMath.sqrt((a*a + b*b)/(det*det));
-//         return (int)(len*65536.0);
-//     }
-
-//     public int getType() {
-//     }
-
-}
--- a/jdk/src/share/classes/sun/net/www/protocol/file/FileURLConnection.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/net/www/protocol/file/FileURLConnection.java	Thu Sep 02 12:17:21 2010 -0700
@@ -59,7 +59,7 @@
     String filename;
     boolean isDirectory = false;
     boolean exists = false;
-    List files;
+    List<String> files;
 
     long length = -1;
     long lastModified = 0;
@@ -81,7 +81,10 @@
                 filename = file.toString();
                 isDirectory = file.isDirectory();
                 if (isDirectory) {
-                    files = (List) Arrays.asList(file.list());
+                    String[] fileList = file.list();
+                    if (fileList == null)
+                        throw new FileNotFoundException(filename + " exists, but is not accessible");
+                    files = Arrays.<String>asList(fileList);
                 } else {
 
                     is = new BufferedInputStream(new FileInputStream(filename));
@@ -197,7 +200,7 @@
                 Collections.sort(files, Collator.getInstance());
 
                 for (int i = 0 ; i < files.size() ; i++) {
-                    String fileName = (String)files.get(i);
+                    String fileName = files.get(i);
                     buf.append(fileName);
                     buf.append("\n");
                 }
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1768,6 +1768,10 @@
         // Not really necessary for a tunnel, but can't hurt
         requests.setIfNotSet("Accept", acceptString);
 
+        if (http.getHttpKeepAliveSet()) {
+            requests.setIfNotSet("Proxy-Connection", "keep-alive");
+        }
+
         setPreemptiveProxyAuthentication(requests);
 
          /* Log the CONNECT request */
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu Sep 02 12:17:21 2010 -0700
@@ -536,9 +536,11 @@
         }
     }
 
-    private long read0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (readLock) {
             synchronized (stateLock) {
                 ensureOpen();
@@ -552,7 +554,7 @@
                     return 0;
                 readerThread = NativeThread.current();
                 do {
-                    n = IOUtil.read(fd, bufs, nd);
+                    n = IOUtil.read(fd, dsts, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -563,15 +565,6 @@
         }
     }
 
-    public long read(ByteBuffer[] dsts, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
-           throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return read0(Util.subsequence(dsts, offset, length));
-    }
-
     public int write(ByteBuffer buf) throws IOException {
         if (buf == null)
             throw new NullPointerException();
@@ -599,9 +592,11 @@
         }
     }
 
-    private long write0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (writeLock) {
             synchronized (stateLock) {
                 ensureOpen();
@@ -615,7 +610,7 @@
                     return 0;
                 writerThread = NativeThread.current();
                 do {
-                    n = IOUtil.write(fd, bufs, nd);
+                    n = IOUtil.write(fd, srcs, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -626,15 +621,6 @@
         }
     }
 
-    public long write(ByteBuffer[] srcs, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
-            throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return write0(Util.subsequence(srcs, offset, length));
-    }
-
     protected void implConfigureBlocking(boolean block) throws IOException {
         IOUtil.configureBlocking(fd, block);
     }
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Sep 02 12:17:21 2010 -0700
@@ -143,7 +143,11 @@
         }
     }
 
-    private long read0(ByteBuffer[] dsts) throws IOException {
+    public long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
+            throw new IndexOutOfBoundsException();
         ensureOpen();
         if (!readable)
             throw new NonReadableChannelException();
@@ -156,7 +160,7 @@
                 if (!isOpen())
                     return 0;
                 do {
-                    n = IOUtil.read(fd, dsts, nd);
+                    n = IOUtil.read(fd, dsts, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -167,15 +171,6 @@
         }
     }
 
-    public long read(ByteBuffer[] dsts, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
-           throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return read0(Util.subsequence(dsts, offset, length));
-    }
-
     public int write(ByteBuffer src) throws IOException {
         ensureOpen();
         if (!writable)
@@ -200,7 +195,11 @@
         }
     }
 
-    private long write0(ByteBuffer[] srcs) throws IOException {
+    public long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
+            throw new IndexOutOfBoundsException();
         ensureOpen();
         if (!writable)
             throw new NonWritableChannelException();
@@ -213,7 +212,7 @@
                 if (!isOpen())
                     return 0;
                 do {
-                    n = IOUtil.write(fd, srcs, nd);
+                    n = IOUtil.write(fd, srcs, offset, length, nd);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(n);
             } finally {
@@ -224,16 +223,6 @@
         }
     }
 
-    public long write(ByteBuffer[] srcs, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
-           throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return write0(Util.subsequence(srcs, offset, length));
-    }
-
-
     // -- Other operations --
 
     public long position() throws IOException {
@@ -440,24 +429,45 @@
         }
     }
 
-    private long transferToTrustedChannel(long position, int icount,
+    // Maximum size to map when using a mapped buffer
+    private static final long MAPPED_TRANSFER_SIZE = 8L*1024L*1024L;
+
+    private long transferToTrustedChannel(long position, long count,
                                           WritableByteChannel target)
         throws IOException
     {
-        if (  !((target instanceof FileChannelImpl)
-                || (target instanceof SelChImpl)))
+        boolean isSelChImpl = (target instanceof SelChImpl);
+        if (!((target instanceof FileChannelImpl) || isSelChImpl))
             return IOStatus.UNSUPPORTED;
 
         // Trusted target: Use a mapped buffer
-        MappedByteBuffer dbb = null;
-        try {
-            dbb = map(MapMode.READ_ONLY, position, icount);
-            // ## Bug: Closing this channel will not terminate the write
-            return target.write(dbb);
-        } finally {
-            if (dbb != null)
-                unmap(dbb);
+        long remaining = count;
+        while (remaining > 0L) {
+            long size = Math.min(remaining, MAPPED_TRANSFER_SIZE);
+            try {
+                MappedByteBuffer dbb = map(MapMode.READ_ONLY, position, size);
+                try {
+                    // ## Bug: Closing this channel will not terminate the write
+                    int n = target.write(dbb);
+                    assert n >= 0;
+                    remaining -= n;
+                    if (isSelChImpl) {
+                        // one attempt to write to selectable channel
+                        break;
+                    }
+                    assert n > 0;
+                    position += n;
+                } finally {
+                    unmap(dbb);
+                }
+            } catch (IOException ioe) {
+                // Only throw exception if no bytes have been written
+                if (remaining == count)
+                    throw ioe;
+                break;
+            }
         }
+        return count - remaining;
     }
 
     private long transferToArbitraryChannel(long position, int icount,
@@ -535,20 +545,34 @@
                                          long position, long count)
         throws IOException
     {
-        // Note we could loop here to accumulate more at once
         synchronized (src.positionLock) {
-            long p = src.position();
-            int icount = (int)Math.min(Math.min(count, Integer.MAX_VALUE),
-                                       src.size() - p);
-            // ## Bug: Closing this channel will not terminate the write
-            MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, icount);
-            try {
-                long n = write(bb, position);
-                src.position(p + n);
-                return n;
-            } finally {
-                unmap(bb);
+            long pos = src.position();
+            long max = Math.min(count, src.size() - pos);
+
+            long remaining = max;
+            long p = pos;
+            while (remaining > 0L) {
+                long size = Math.min(remaining, MAPPED_TRANSFER_SIZE);
+                // ## Bug: Closing this channel will not terminate the write
+                MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, size);
+                try {
+                    long n = write(bb, position);
+                    assert n > 0;
+                    p += n;
+                    position += n;
+                    remaining -= n;
+                } catch (IOException ioe) {
+                    // Only throw exception if no bytes have been written
+                    if (remaining == max)
+                        throw ioe;
+                    break;
+                } finally {
+                    unmap(bb);
+                }
             }
+            long nwritten = max - remaining;
+            src.position(pos + nwritten);
+            return nwritten;
         }
     }
 
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java	Thu Sep 02 12:17:21 2010 -0700
@@ -38,34 +38,6 @@
 
     private IOUtil() { }                // No instantiation
 
-    /*
-     * Returns the index of first buffer in bufs with remaining,
-     * or -1 if there is nothing left
-     */
-    private static int remaining(ByteBuffer[] bufs) {
-        int numBufs = bufs.length;
-        for (int i=0; i<numBufs; i++) {
-            if (bufs[i].hasRemaining()) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /*
-     * Returns a new ByteBuffer array with only unfinished buffers in it
-     */
-    private static ByteBuffer[] skipBufs(ByteBuffer[] bufs,
-                                         int nextWithRemaining)
-    {
-        int newSize = bufs.length - nextWithRemaining;
-        ByteBuffer[] temp = new ByteBuffer[newSize];
-        for (int i=0; i<newSize; i++) {
-            temp[i] = bufs[i + nextWithRemaining];
-        }
-        return temp;
-    }
-
     static int write(FileDescriptor fd, ByteBuffer src, long position,
                      NativeDispatcher nd, Object lock)
         throws IOException
@@ -93,7 +65,7 @@
             }
             return n;
         } finally {
-            Util.releaseTemporaryDirectBuffer(bb);
+            Util.offerFirstTemporaryDirectBuffer(bb);
         }
     }
 
@@ -125,88 +97,81 @@
     static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
         throws IOException
     {
-        int nextWithRemaining = remaining(bufs);
-        // if all bufs are empty we should return immediately
-        if (nextWithRemaining < 0)
-            return 0;
-        // If some bufs are empty we should skip them
-        if (nextWithRemaining > 0)
-            bufs = skipBufs(bufs, nextWithRemaining);
+        return write(fd, bufs, 0, bufs.length, nd);
+    }
 
-        int numBufs = bufs.length;
+    static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
+                      NativeDispatcher nd)
+        throws IOException
+    {
+        IOVecWrapper vec = IOVecWrapper.get(length);
 
-        // Create shadow to ensure DirectByteBuffers are used
-        ByteBuffer[] shadow = new ByteBuffer[numBufs];
+        boolean completed = false;
+        int iov_len = 0;
         try {
-            for (int i=0; i<numBufs; i++) {
-                if (!(bufs[i] instanceof DirectBuffer)) {
-                    int pos = bufs[i].position();
-                    int lim = bufs[i].limit();
-                    assert (pos <= lim);
-                    int rem = (pos <= lim ? lim - pos : 0);
+
+            // Iterate over buffers to populate native iovec array.
+            int count = offset + length;
+            for (int i=offset; i<count; i++) {
+                ByteBuffer buf = bufs[i];
+                int pos = buf.position();
+                int lim = buf.limit();
+                assert (pos <= lim);
+                int rem = (pos <= lim ? lim - pos : 0);
+                if (rem > 0) {
+                    vec.setBuffer(iov_len, buf, pos, rem);
+
+                    // allocate shadow buffer to ensure I/O is done with direct buffer
+                    if (!(buf instanceof DirectBuffer)) {
+                        ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
+                        shadow.put(buf);
+                        shadow.flip();
+                        vec.setShadow(iov_len, shadow);
+                        buf.position(pos);  // temporarily restore position in user buffer
+                        buf = shadow;
+                        pos = shadow.position();
+                    }
 
-                    ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
-                    shadow[i] = bb;
-                    // Leave slow buffer position untouched; it will be updated
-                    // after we see how many bytes were really written out
-                    bb.put(bufs[i]);
-                    bufs[i].position(pos);
-                    bb.flip();
-                } else {
-                    shadow[i] = bufs[i];
+                    vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
+                    vec.putLen(iov_len, rem);
+                    iov_len++;
                 }
             }
+            if (iov_len == 0)
+                return 0L;
+
+            long bytesWritten = nd.writev(fd, vec.address, iov_len);
+
+            // Notify the buffers how many bytes were taken
+            long left = bytesWritten;
+            for (int j=0; j<iov_len; j++) {
+                if (left > 0) {
+                    ByteBuffer buf = vec.getBuffer(j);
+                    int pos = vec.getPosition(j);
+                    int rem = vec.getRemaining(j);
+                    int n = (left > rem) ? rem : (int)left;
+                    buf.position(pos + n);
+                    left -= n;
+                }
+                // return shadow buffers to buffer pool
+                ByteBuffer shadow = vec.getShadow(j);
+                if (shadow != null)
+                    Util.offerLastTemporaryDirectBuffer(shadow);
+                vec.clearRefs(j);
+            }
 
-            IOVecWrapper vec = null;
-            long bytesWritten = 0;
-            try {
-                // Create a native iovec array
-                vec= new IOVecWrapper(numBufs);
-
-                // Fill in the iovec array with appropriate data
-                for (int i=0; i<numBufs; i++) {
-                    ByteBuffer nextBuffer = shadow[i];
-                    // put in the buffer addresses
-                    long pos = nextBuffer.position();
-                    long len = nextBuffer.limit() - pos;
-                    vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
-                    vec.putLen(i, len);
-                }
-
-                // Invoke native call to fill the buffers
-                bytesWritten = nd.writev(fd, vec.address, numBufs);
-            } finally {
-                vec.free();
-            }
-            long returnVal = bytesWritten;
+            completed = true;
+            return bytesWritten;
 
-            // Notify the buffers how many bytes were taken
-            for (int i=0; i<numBufs; i++) {
-                ByteBuffer nextBuffer = bufs[i];
-                int pos = nextBuffer.position();
-                int lim = nextBuffer.limit();
-                assert (pos <= lim);
-                int len = (pos <= lim ? lim - pos : lim);
-                if (bytesWritten >= len) {
-                    bytesWritten -= len;
-                    int newPosition = pos + len;
-                    nextBuffer.position(newPosition);
-                } else { // Buffers not completely filled
-                    if (bytesWritten > 0) {
-                        assert(pos + bytesWritten < (long)Integer.MAX_VALUE);
-                        int newPosition = (int)(pos + bytesWritten);
-                        nextBuffer.position(newPosition);
-                    }
-                    break;
-                }
-            }
-            return returnVal;
         } finally {
-            // return any substituted buffers to cache
-            for (int i=0; i<numBufs; i++) {
-                ByteBuffer bb = shadow[i];
-                if (bb != null && bb != bufs[i]) {
-                    Util.releaseTemporaryDirectBuffer(bb);
+            // if an error occurred then clear refs to buffers and return any shadow
+            // buffers to cache
+            if (!completed) {
+                for (int j=0; j<iov_len; j++) {
+                    ByteBuffer shadow = vec.getShadow(j);
+                    if (shadow != null)
+                        Util.offerLastTemporaryDirectBuffer(shadow);
+                    vec.clearRefs(j);
                 }
             }
         }
@@ -231,7 +196,7 @@
                 dst.put(bb);
             return n;
         } finally {
-            Util.releaseTemporaryDirectBuffer(bb);
+            Util.offerFirstTemporaryDirectBuffer(bb);
         }
     }
 
@@ -262,92 +227,85 @@
     static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
         throws IOException
     {
-        int nextWithRemaining = remaining(bufs);
-        // if all bufs are empty we should return immediately
-        if (nextWithRemaining < 0)
-            return 0;
-        // If some bufs are empty we should skip them
-        if (nextWithRemaining > 0)
-            bufs = skipBufs(bufs, nextWithRemaining);
+        return read(fd, bufs, 0, bufs.length, nd);
+    }
+
+    static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
+                     NativeDispatcher nd)
+        throws IOException
+    {
+        IOVecWrapper vec = IOVecWrapper.get(length);
+
+        boolean completed = false;
+        int iov_len = 0;
+        try {
 
-        int numBufs = bufs.length;
+            // Iterate over buffers to populate native iovec array.
+            int count = offset + length;
+            for (int i=offset; i<count; i++) {
+                ByteBuffer buf = bufs[i];
+                if (buf.isReadOnly())
+                    throw new IllegalArgumentException("Read-only buffer");
+                int pos = buf.position();
+                int lim = buf.limit();
+                assert (pos <= lim);
+                int rem = (pos <= lim ? lim - pos : 0);
+
+                if (rem > 0) {
+                    vec.setBuffer(iov_len, buf, pos, rem);
 
-        // Read into the shadow to ensure DirectByteBuffers are used
-        ByteBuffer[] shadow = new ByteBuffer[numBufs];
-        boolean usingSlowBuffers = false;
-        try {
-            for (int i=0; i<numBufs; i++) {
-                if (bufs[i].isReadOnly())
-                    throw new IllegalArgumentException("Read-only buffer");
-                if (!(bufs[i] instanceof DirectBuffer)) {
-                    shadow[i] = Util.getTemporaryDirectBuffer(bufs[i].remaining());
-                    usingSlowBuffers = true;
-                } else {
-                    shadow[i] = bufs[i];
+                    // allocate shadow buffer to ensure I/O is done with direct buffer
+                    if (!(buf instanceof DirectBuffer)) {
+                        ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
+                        vec.setShadow(iov_len, shadow);
+                        buf = shadow;
+                        pos = shadow.position();
+                    }
+
+                    vec.putBase(iov_len, ((DirectBuffer)buf).address() + pos);
+                    vec.putLen(iov_len, rem);
+                    iov_len++;
                 }
             }
+            if (iov_len == 0)
+                return 0L;
+
+            long bytesRead = nd.readv(fd, vec.address, iov_len);
+
+            // Notify the buffers how many bytes were read
+            long left = bytesRead;
+            for (int j=0; j<iov_len; j++) {
+                ByteBuffer shadow = vec.getShadow(j);
+                if (left > 0) {
+                    ByteBuffer buf = vec.getBuffer(j);
+                    int rem = vec.getRemaining(j);
+                    int n = (left > rem) ? rem : (int)left;
+                    if (shadow == null) {
+                        int pos = vec.getPosition(j);
+                        buf.position(pos + n);
+                    } else {
+                        shadow.limit(shadow.position() + n);
+                        buf.put(shadow);
+                    }
+                    left -= n;
+                }
+                if (shadow != null)
+                    Util.offerLastTemporaryDirectBuffer(shadow);
+                vec.clearRefs(j);
+            }
 
-            IOVecWrapper vec = null;
-            long bytesRead = 0;
-            try {
-                // Create a native iovec array
-                vec = new IOVecWrapper(numBufs);
-
-                // Fill in the iovec array with appropriate data
-                for (int i=0; i<numBufs; i++) {
-                    ByteBuffer nextBuffer = shadow[i];
-                    // put in the buffer addresses
-                    long pos = nextBuffer.position();
-                    long len = nextBuffer.remaining();
-                    vec.putBase(i, ((DirectBuffer)nextBuffer).address() + pos);
-                    vec.putLen(i, len);
-                }
-
-                // Invoke native call to fill the buffers
-                bytesRead = nd.readv(fd, vec.address, numBufs);
-            } finally {
-                vec.free();
-            }
-            long returnVal = bytesRead;
+            completed = true;
+            return bytesRead;
 
-            // Notify the buffers how many bytes were read
-            for (int i=0; i<numBufs; i++) {
-                ByteBuffer nextBuffer = shadow[i];
-                // Note: should this have been cached from above?
-                int pos = nextBuffer.position();
-                int len = nextBuffer.remaining();
-                if (bytesRead >= len) {
-                    bytesRead -= len;
-                    int newPosition = pos + len;
-                    nextBuffer.position(newPosition);
-                } else { // Buffers not completely filled
-                    if (bytesRead > 0) {
-                        assert(pos + bytesRead < (long)Integer.MAX_VALUE);
-                        int newPosition = (int)(pos + bytesRead);
-                        nextBuffer.position(newPosition);
-                    }
-                    break;
-                }
-            }
-
-            // Put results from shadow into the slow buffers
-            if (usingSlowBuffers) {
-                for (int i=0; i<numBufs; i++) {
-                    if (!(bufs[i] instanceof DirectBuffer)) {
-                        shadow[i].flip();
-                        bufs[i].put(shadow[i]);
-                    }
-                }
-            }
-            return returnVal;
         } finally {
-            // return any substituted buffers to cache
-            if (usingSlowBuffers) {
-                for (int i=0; i<numBufs; i++) {
-                    ByteBuffer bb = shadow[i];
-                    if (bb != null && bb != bufs[i]) {
-                        Util.releaseTemporaryDirectBuffer(bb);
-                    }
+            // if an error occurred then clear refs to buffers and return any shadow
+            // buffers to cache
+            if (!completed) {
+                for (int j=0; j<iov_len; j++) {
+                    ByteBuffer shadow = vec.getShadow(j);
+                    if (shadow != null)
+                        Util.offerLastTemporaryDirectBuffer(shadow);
+                    vec.clearRefs(j);
                 }
             }
         }
--- a/jdk/src/share/classes/sun/nio/ch/IOVecWrapper.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/nio/ch/IOVecWrapper.java	Thu Sep 02 12:17:21 2010 -0700
@@ -25,6 +25,7 @@
 
 package sun.nio.ch;
 
+import java.nio.ByteBuffer;
 import sun.misc.*;
 
 
@@ -43,23 +44,98 @@
 class IOVecWrapper {
 
     // Miscellaneous constants
-    static int BASE_OFFSET = 0;
-    static int LEN_OFFSET;
-    static int SIZE_IOVEC;
+    private static final int BASE_OFFSET = 0;
+    private static final int LEN_OFFSET;
+    private static final int SIZE_IOVEC;
 
     // The iovec array
-    private AllocatedNativeObject vecArray;
+    private final AllocatedNativeObject vecArray;
+
+    // Number of elements in iovec array
+    private final int size;
+
+    // Buffers and position/remaining corresponding to elements in iovec array
+    private final ByteBuffer[] buf;
+    private final int[] position;
+    private final int[] remaining;
+
+    // Shadow buffers for cases when original buffer is substituted
+    private final ByteBuffer[] shadow;
 
     // Base address of this array
-    long address;
+    final long address;
 
     // Address size in bytes
     static int addressSize;
 
-    IOVecWrapper(int newSize) {
-        newSize = (newSize + 1) * SIZE_IOVEC;
-        vecArray = new AllocatedNativeObject(newSize, false);
-        address = vecArray.address();
+    private static class Deallocator implements Runnable {
+        private final AllocatedNativeObject obj;
+        Deallocator(AllocatedNativeObject obj) {
+            this.obj = obj;
+        }
+        public void run() {
+            obj.free();
+        }
+    }
+
+    // per thread IOVecWrapper
+    private static final ThreadLocal<IOVecWrapper> cached =
+        new ThreadLocal<IOVecWrapper>();
+
+    private IOVecWrapper(int size) {
+        this.size      = size;
+        this.buf       = new ByteBuffer[size];
+        this.position  = new int[size];
+        this.remaining = new int[size];
+        this.shadow    = new ByteBuffer[size];
+        this.vecArray  = new AllocatedNativeObject(size * SIZE_IOVEC, false);
+        this.address   = vecArray.address();
+    }
+
+    static IOVecWrapper get(int size) {
+        IOVecWrapper wrapper = cached.get();
+        if (wrapper != null && wrapper.size < size) {
+            // not big enough; eagerly release memory
+            wrapper.vecArray.free();
+            wrapper = null;
+        }
+        if (wrapper == null) {
+            wrapper = new IOVecWrapper(size);
+            Cleaner.create(wrapper, new Deallocator(wrapper.vecArray));
+            cached.set(wrapper);
+        }
+        return wrapper;
+    }
+
+    void setBuffer(int i, ByteBuffer buf, int pos, int rem) {
+        this.buf[i] = buf;
+        this.position[i] = pos;
+        this.remaining[i] = rem;
+    }
+
+    void setShadow(int i, ByteBuffer buf) {
+        shadow[i] = buf;
+    }
+
+    ByteBuffer getBuffer(int i) {
+        return buf[i];
+    }
+
+    int getPosition(int i) {
+        return position[i];
+    }
+
+    int getRemaining(int i) {
+        return remaining[i];
+    }
+
+    ByteBuffer getShadow(int i) {
+        return shadow[i];
+    }
+
+    void clearRefs(int i) {
+        buf[i] = null;
+        shadow[i] = null;
     }
 
     void putBase(int i, long base) {
@@ -78,10 +154,6 @@
             vecArray.putLong(offset, len);
     }
 
-    void free() {
-        vecArray.free();
-    }
-
     static {
         addressSize = Util.unsafe().addressSize();
         LEN_OFFSET = addressSize;
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu Sep 02 12:17:21 2010 -0700
@@ -385,9 +385,11 @@
         }
     }
 
-    private long read0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (readLock) {
             if (!ensureReadOpen())
                 return -1;
@@ -401,7 +403,7 @@
                 }
 
                 for (;;) {
-                    n = IOUtil.read(fd, bufs, nd);
+                    n = IOUtil.read(fd, dsts, offset, length, nd);
                     if ((n == IOStatus.INTERRUPTED) && isOpen())
                         continue;
                     return IOStatus.normalize(n);
@@ -418,15 +420,6 @@
         }
     }
 
-    public long read(ByteBuffer[] dsts, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
-            throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return read0(Util.subsequence(dsts, offset, length));
-    }
-
     public int write(ByteBuffer buf) throws IOException {
         if (buf == null)
             throw new NullPointerException();
@@ -458,9 +451,11 @@
         }
     }
 
-    public long write0(ByteBuffer[] bufs) throws IOException {
-        if (bufs == null)
-            throw new NullPointerException();
+    public long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException
+    {
+        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
+            throw new IndexOutOfBoundsException();
         synchronized (writeLock) {
             ensureWriteOpen();
             long n = 0;
@@ -472,7 +467,7 @@
                     writerThread = NativeThread.current();
                 }
                 for (;;) {
-                    n = IOUtil.write(fd, bufs, nd);
+                    n = IOUtil.write(fd, srcs, offset, length, nd);
                     if ((n == IOStatus.INTERRUPTED) && isOpen())
                         continue;
                     return IOStatus.normalize(n);
@@ -489,15 +484,6 @@
         }
     }
 
-    public long write(ByteBuffer[] srcs, int offset, int length)
-        throws IOException
-    {
-        if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
-            throw new IndexOutOfBoundsException();
-        // ## Fix IOUtil.write so that we can avoid this array copy
-        return write0(Util.subsequence(srcs, offset, length));
-    }
-
     // package-private
     int sendOutOfBandData(byte b) throws IOException {
         synchronized (writeLock) {
--- a/jdk/src/share/classes/sun/nio/ch/Util.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/nio/ch/Util.java	Thu Sep 02 12:17:21 2010 -0700
@@ -41,67 +41,180 @@
 
 class Util {
 
-
     // -- Caches --
 
     // The number of temp buffers in our pool
-    private static final int TEMP_BUF_POOL_SIZE = 3;
+    private static final int TEMP_BUF_POOL_SIZE = 8;
 
-    // Per-thread soft cache of the last temporary direct buffer
-    private static ThreadLocal<SoftReference<ByteBuffer>>[] bufferPool;
+    // Per-thread cache of temporary direct buffers
+    private static ThreadLocal<BufferCache> bufferCache =
+        new ThreadLocal<BufferCache>()
+    {
+        @Override
+        protected BufferCache initialValue() {
+            return new BufferCache();
+        }
+    };
+
+    /**
+     * A simple cache of direct buffers.
+     */
+    private static class BufferCache {
+        // the array of buffers
+        private ByteBuffer[] buffers;
 
-    @SuppressWarnings("unchecked")
-    static ThreadLocal<SoftReference<ByteBuffer>>[] createThreadLocalBufferPool() {
-        return new ThreadLocal[TEMP_BUF_POOL_SIZE];
-    }
+        // the number of buffers in the cache
+        private int count;
+
+        // the index of the first valid buffer (undefined if count == 0)
+        private int start;
+
+        private int next(int i) {
+            return (i + 1) % TEMP_BUF_POOL_SIZE;
+        }
+
+        BufferCache() {
+            buffers = new ByteBuffer[TEMP_BUF_POOL_SIZE];
+        }
+
+        /**
+         * Removes and returns a buffer from the cache of at least the given
+         * size (or null if no suitable buffer is found).
+         */
+        ByteBuffer get(int size) {
+            if (count == 0)
+                return null;  // cache is empty
 
-    static {
-        bufferPool = createThreadLocalBufferPool();
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++)
-            bufferPool[i] = new ThreadLocal<SoftReference<ByteBuffer>>();
-    }
+            ByteBuffer[] buffers = this.buffers;
 
-    static ByteBuffer getTemporaryDirectBuffer(int size) {
-        ByteBuffer buf = null;
-        // Grab a buffer if available
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference<ByteBuffer> ref = bufferPool[i].get();
-            if ((ref != null) && ((buf = ref.get()) != null) &&
-                (buf.capacity() >= size)) {
-                buf.rewind();
-                buf.limit(size);
-                bufferPool[i].set(null);
-                return buf;
+            // search for suitable buffer (often the first buffer will do)
+            ByteBuffer buf = buffers[start];
+            if (buf.capacity() < size) {
+                buf = null;
+                int i = start;
+                while ((i = next(i)) != start) {
+                    ByteBuffer bb = buffers[i];
+                    if (bb == null)
+                        break;
+                    if (bb.capacity() >= size) {
+                        buf = bb;
+                        break;
+                    }
+                }
+                if (buf == null)
+                    return null;
+                // move first element to here to avoid re-packing
+                buffers[i] = buffers[start];
+            }
+
+            // remove first element
+            buffers[start] = null;
+            start = next(start);
+            count--;
+
+            // prepare the buffer and return it
+            buf.rewind();
+            buf.limit(size);
+            return buf;
+        }
+
+        boolean offerFirst(ByteBuffer buf) {
+            if (count >= TEMP_BUF_POOL_SIZE) {
+                return false;
+            } else {
+                start = (start + TEMP_BUF_POOL_SIZE - 1) % TEMP_BUF_POOL_SIZE;
+                buffers[start] = buf;
+                count++;
+                return true;
             }
         }
 
-        // Make a new one
-        return ByteBuffer.allocateDirect(size);
-    }
-
-    static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
-        if (buf == null)
-            return;
-        // Put it in an empty slot if such exists
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference<ByteBuffer> ref = bufferPool[i].get();
-            if ((ref == null) || (ref.get() == null)) {
-                bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
-                return;
-            }
-        }
-        // Otherwise replace a smaller one in the cache if such exists
-        for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
-            SoftReference<ByteBuffer> ref = bufferPool[i].get();
-            ByteBuffer inCacheBuf = ref.get();
-            if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) {
-                bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
-                return;
+        boolean offerLast(ByteBuffer buf) {
+            if (count >= TEMP_BUF_POOL_SIZE) {
+                return false;
+            } else {
+                int next = (start + count) % TEMP_BUF_POOL_SIZE;
+                buffers[next] = buf;
+                count++;
+                return true;
             }
         }
 
-        // release memory
-       ((DirectBuffer)buf).cleaner().clean();
+        boolean isEmpty() {
+            return count == 0;
+        }
+
+        ByteBuffer removeFirst() {
+            assert count > 0;
+            ByteBuffer buf = buffers[start];
+            buffers[start] = null;
+            start = next(start);
+            count--;
+            return buf;
+        }
+    }
+
+    /**
+     * Returns a temporary buffer of at least the given size
+     */
+    static ByteBuffer getTemporaryDirectBuffer(int size) {
+        BufferCache cache = bufferCache.get();
+        ByteBuffer buf = cache.get(size);
+        if (buf != null) {
+            return buf;
+        } else {
+            // No suitable buffer in the cache so we need to allocate a new
+            // one. To avoid the cache growing then we remove the first
+            // buffer from the cache and free it.
+            if (!cache.isEmpty()) {
+                buf = cache.removeFirst();
+                free(buf);
+            }
+            return ByteBuffer.allocateDirect(size);
+        }
+    }
+
+    /**
+     * Releases a temporary buffer by returning to the cache or freeing it.
+     */
+    static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
+        offerFirstTemporaryDirectBuffer(buf);
+    }
+
+    /**
+     * Releases a temporary buffer by returning to the cache or freeing it. If
+     * returning to the cache then insert it at the start so that it is
+     * likely to be returned by a subsequent call to getTemporaryDirectBuffer.
+     */
+    static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) {
+        assert buf != null;
+        BufferCache cache = bufferCache.get();
+        if (!cache.offerFirst(buf)) {
+            // cache is full
+            free(buf);
+        }
+    }
+
+    /**
+     * Releases a temporary buffer by returning to the cache or freeing it. If
+     * returning to the cache then insert it at the end. This makes it
+     * suitable for scatter/gather operations where the buffers are returned to
+     * cache in same order that they were obtained.
+     */
+    static void offerLastTemporaryDirectBuffer(ByteBuffer buf) {
+        assert buf != null;
+        BufferCache cache = bufferCache.get();
+        if (!cache.offerLast(buf)) {
+            // cache is full
+            free(buf);
+        }
+    }
+
+    /**
+     * Frees the memory for the given direct buffer
+     */
+    private static void free(ByteBuffer buf) {
+        ((DirectBuffer)buf).cleaner().clean();
     }
 
     private static class SelectorWrapper {
--- a/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/tools/jconsole/resources/JConsoleResources.java	Thu Sep 02 12:17:21 2010 -0700
@@ -46,8 +46,6 @@
  */
 public class JConsoleResources extends ListResourceBundle {
 
-    private static final String cr = System.getProperty("line.separator");
-
     /**
      * Returns the contents of this <code>ResourceBundle</code>.
      *
@@ -56,8 +54,8 @@
      * @return the contents of this <code>ResourceBundle</code>.
      */
     protected Object[][] getContents0() {
-        return new Object[][] {
-        // NOTE 1: The value strings in this file containing "{0}" are
+        Object[][] temp = new Object[][] {
+                // NOTE 1: The value strings in this file containing "{0}" are
         //         processed by the java.text.MessageFormat class.  Any
         //         single quotes appearing in these strings need to be
         //         doubled up.
@@ -98,7 +96,7 @@
         {"Attributes","Attributes"},
         {"Blank", "Blank"},
         {"BlockedCount WaitedCount",
-             "Total blocked: {0}  Total waited: {1}" + cr},
+             "Total blocked: {0}  Total waited: {1}\n"},
         {"Boot class path","Boot class path"},
         {"BorderedComponent.moreOrLessButton.toolTip", "Toggle to show more or less information"},
         {"CPU Usage","CPU Usage"},
@@ -271,21 +269,21 @@
         {"Minimize All.mnemonic", 'M'},
         {"Minus Version", "This is {0} version {1}"},
         {"Monitor locked",
-             "   - locked {0}" + cr},
+             "   - locked {0}\n"},
         {"Motif","Motif"},
         {"Name Build and Mode","{0} (build {1}, {2})"},
         {"Name and Build","{0} (build {1})"},
         {"Name","Name"},
         {"Name: ","Name: "},
         {"Name State",
-             "Name: {0}" + cr +
-             "State: {1}" + cr},
+             "Name: {0}\n" +
+             "State: {1}\n"},
         {"Name State LockName",
-             "Name: {0}" + cr +
-             "State: {1} on {2}" + cr},
+             "Name: {0}\n" +
+             "State: {1} on {2}\n"},
         {"Name State LockName LockOwner",
-             "Name: {0}" + cr +
-             "State: {1} on {2} owned by: {3}" + cr},
+             "Name: {0}\n" +
+             "State: {1} on {2} owned by: {3}\n"},
         {"New Connection...", "New Connection..."},
         {"New Connection....mnemonic", 'N'},
         {"New value applied","New value applied"},
@@ -351,7 +349,7 @@
         {"Size Mb","{0} Mb"},
         {"Source","Source"},
         {"Stack trace",
-             cr + "Stack trace: " + cr},
+              "\nStack trace: \n"},
         {"Success:","Success:"},
         // Note: SummaryTab.headerDateTimeFormat can be one the following:
         // 1. A combination of two styles for date and time, using the
@@ -433,22 +431,27 @@
         {"plot", "plot"},
         {"visualize","visualize"},
         {"zz usage text",
-             "Usage: {0} [ -interval=n ] [ -notile ] [ -pluginpath <path> ] [ -version ] [ connection ... ]" + cr +
-             cr +
-             "  -interval   Set the update interval to n seconds (default is 4 seconds)" + cr +
-             "  -notile     Do not tile windows initially (for two or more connections)" + cr +
-             "  -pluginpath Specify the path that jconsole uses to look up the plugins" + cr +
-             "  -version    Print program version" + cr +
-             cr +
-             "  connection = pid || host:port || JMX URL (service:jmx:<protocol>://...)" + cr +
-             "  pid         The process id of a target process" + cr +
-             "  host        A remote host name or IP address" + cr +
-             "  port        The port number for the remote connection" + cr +
-             cr +
-             "  -J          Specify the input arguments to the Java virtual machine" + cr +
+             "Usage: {0} [ -interval=n ] [ -notile ] [ -pluginpath <path> ] [ -version ] [ connection ... ]\n\n" +
+             "  -interval   Set the update interval to n seconds (default is 4 seconds)\n" +
+             "  -notile     Do not tile windows initially (for two or more connections)\n" +
+             "  -pluginpath Specify the path that jconsole uses to look up the plugins\n\n" +
+             "  -version    Print program version\n" +
+             "  connection = pid || host:port || JMX URL (service:jmx:<protocol>://...)\n" +
+             "  pid         The process id of a target process\n" +
+             "  host        A remote host name or IP address\n" +
+             "  port        The port number for the remote connection\n\n" +
+             "  -J          Specify the input arguments to the Java virtual machine\n" +
              "              on which jconsole is running"},
         // END OF MATERIAL TO LOCALIZE
         };
+
+        String ls = System.getProperty("line.separator");
+        for(int i=0;i<temp.length;i++) {
+            temp[i][1] = temp[i][1].toString().replaceAll("\n",ls);
+        }
+
+        return temp;
+
     }
 
     public synchronized Object[][] getContents() {
--- a/jdk/src/share/classes/sun/tools/native2ascii/resources/MsgNative2ascii.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/tools/native2ascii/resources/MsgNative2ascii.java	Thu Sep 02 12:17:21 2010 -0700
@@ -30,12 +30,14 @@
 public class MsgNative2ascii extends ListResourceBundle {
 
     public Object[][] getContents() {
-        return new Object[][] {
+        Object[][] temp = new Object[][] {
         {"err.bad.arg", "-encoding requires argument"},
         {"err.cannot.read",  "{0} could not be read."},
         {"err.cannot.write", "{0} could not be written."},
         {"usage", "Usage: native2ascii" +
          " [-reverse] [-encoding encoding] [inputfile [outputfile]]"},
         };
+
+        return temp;
     }
 }
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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,8 @@
                                      "Central European Summer Time", "CEST"};
         String CHAST[] = new String[] {"Chatham Standard Time", "CHAST",
                                        "Chatham Daylight Time", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Central Indonesia Time", "CIT",
                                      "Central Indonesia Summer Time", "CIST"};
         String CLT[] = new String[] {"Chile Time", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn Daylight Time", "PDT"};
         String PKT[] = new String[] {"Pakistan Time", "PKT",
                                      "Pakistan Summer Time", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Pacific Standard Time", "PST",
                                      "Pacific Daylight Time", "PDT"};
         String RST[] = new String[] {"Eastern Standard Time", "EST",
@@ -169,8 +173,6 @@
                                           "Eastern Summer Time (Tasmania)", "EST"};
         String TMT[] = new String[] {"Turkmenistan Time", "TMT",
                                      "Turkmenistan Summer Time", "TMST"};
-        String TRUT[] = new String[] {"Truk Time", "TRUT",
-                                      "Truk Summer Time", "TRUST"};
         String ULAT[]= new String[] {"Ulaanbaatar Time", "ULAT",
                                      "Ulaanbaatar Summer Time", "ULAST"};
         String WART[] = new String[] {"Western Argentine Time", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -755,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Vanuatu Time", "VUT",
                                             "Vanuatu Summer Time", "VUST"}},
@@ -793,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Palau Time", "PWT",
                                             "Palau Summer Time", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape Time", "PONT",
-                                             "Ponape Summer Time", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Papua New Guinea Time", "PGT",
                                                    "Papua New Guinea Summer Time", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Cook Is. Time", "CKT",
@@ -807,12 +811,12 @@
                                              "Gilbert Is. Summer Time", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Tonga Time", "TOT",
                                                 "Tonga Summer Time", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Wake Time", "WAKT",
                                            "Wake Summer Time", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Wallis & Futuna Time", "WFT",
                                              "Wallis & Futuna Summer Time", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_de.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Mitteleurop\u00e4ische Sommerzeit", "MESZ"};
         String CHAST[] = new String[] {"Chatham Normalzeit", "CHAST",
                                        "Chatham Sommerzeit", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Zentralindonesische Zeit", "CIT",
                                      "Zentralindonesische Sommerzeit", "CIST"};
         String CLT[] = new String[] {"Chilenische Zeit", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn Sommerzeit", "PDT"};
         String PKT[] = new String[] {"Pakistanische Zeit", "PKT",
                                      "Pakistanische Sommerzeit", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Pazifische Normalzeit", "PST",
                                      "Pazifische Sommerzeit", "PDT"};
         String RST[] = new String[] {"\u00d6stliche Normalzeit", "EST",
@@ -169,8 +173,6 @@
                                           "\u00d6stliche Sommerzeit (Tasmanien)", "EST"};
         String TMT[] = new String[] {"Turkmenische Zeit", "TMT",
                                      "Turkmenische Sommerzeit", "TMST"};
-        String TRUT[] = new String[] {"Truk Zeit", "TRUT",
-                                      "Truk Sommerzeit", "TRUST"};
         String ULAT[]= new String[] {"Ulaanbaatar Zeit", "ULAT",
                                      "Ulaanbaatar Sommerzeit", "ULAST"};
         String WART[] = new String[] {"Westargentinische Zeit", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Davis Zeit", "DAVT",
                                                "Davis Sommerzeit", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Zeit", "DDUT",
                                                         "Dumont-d'Urville Sommerzeit", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Mawson Zeit", "MAWT",
                                                 "Mawson Sommerzeit", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Vanuatu Zeit", "VUT",
                                             "Vanuatu Sommerzeit", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Palau Zeit", "PWT",
                                             "Palau Sommerzeit", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape Zeit", "PONT",
-                                             "Ponape Sommerzeit", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Papua-Neuguinea Zeit", "PGT",
                                                    "Papua-Neuguinea Sommerzeit", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Cook-Inseln Zeit", "CKT",
@@ -804,12 +811,12 @@
                                              "Gilbert-Inseln Sommerzeit", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Tonga Zeit", "TOT",
                                                 "Tonga Sommerzeit", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Wake Zeit", "WAKT",
                                            "Wake Sommerzeit", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Wallis u. Futuna Zeit", "WFT",
                                              "Wallis u. Futuna Sommerzeit", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_es.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Hora de verano de Europa Central", "CEST"};
         String CHAST[] = new String[] {"Hora est\u00e1ndar de Chatham", "CHAST",
                                        "Hora de verano de Chatham", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Hora de Indonesia Central", "CIT",
                                      "Hora de verano de Indonesia Central", "CIST"};
         String CLT[] = new String[] {"Hora de Chile", "CLT",
@@ -153,6 +155,8 @@
                                           "Hora de verano de Pitcairn", "PDT"};
         String PKT[] = new String[] {"Hora de Pakist\u00e1n", "PKT",
                                      "Hora de verano de Pakist\u00e1n", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Hora est\u00e1ndar del Pac\u00edfico", "PST",
                                      "Hora de verano del Pac\u00edfico", "PDT"};
         String RST[] = new String[] {"Hora est\u00e1ndar Oriental", "EST",
@@ -169,8 +173,6 @@
                                           "Hora de verano del Este (Tasmania)", "EST"};
         String TMT[] = new String[] {"Hora de Turkmenist\u00e1n", "TMT",
                                      "Hora de verano de Turkmenist\u00e1n", "TMST"};
-        String TRUT[] =new String[] {"Hora de Truk", "TRUT",
-                                     "Hora de verano de Truk", "TRUST"};
         String ULAT[]= new String[] {"Hora de Ulan Bator", "ULAT",
                                      "Hora de verano de Ulan Bator", "ULAST"};
         String WART[] = new String[] {"Hora de Argentina Occidental", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Hora de Davis", "DAVT",
                                                "Hora de verano de Davis", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Hora de Dumont-d'Urville", "DDUT",
                                                         "Hora de verano de Dumont-d'Urville", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Hora de Mawson", "MAWT",
                                                 "Hora de verano de Mawson", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -533,7 +539,6 @@
                                           "Hora de verano de Filipinas", "PHST"}},
             {"Asia/Muscat", GST},
             {"Asia/Nicosia", EET},
-
             {"Asia/Novokuznetsk", NOVT},
             {"Asia/Novosibirsk", NOVT},
             {"Asia/Oral", new String[] {"Hora de Uralsk", "ORAT",
@@ -753,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Hora de Vanuatu", "VUT",
                                             "Hora de verano de Vanuatu", "VUST"}},
@@ -791,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Hora de Palau", "PWT",
                                             "Hora de verano de Palau", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Hora de Ponape", "PONT",
-                                             "Hora de verano de Ponape", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Hora de Pap\u00faa-Nueva Guinea", "PGT",
                                                    "Hora de verano de Pap\u00faa-Nueva Guinea", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Hora de las islas Cook", "CKT",
@@ -805,12 +811,12 @@
                                              "Hora de verano de las islas Gilbert", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Hora de Tonga", "TOT",
                                                 "Hora de verano de Tonga", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Hora de Wake", "WAKT",
                                            "Hora de verano de Wake", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Hora de Wallis y Futuna", "WFT",
                                              "Hora de verano de Wallis y Futuna", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_fr.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Heure d'\u00e9t\u00e9 d'Europe centrale", "CEST"} ;
         String CHAST[] = new String[] {"Heure standard de Chatham", "CHAST",
                                        "Heure avanc\u00e9e de Chatham", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Heure d'Indon\u00e9sie centrale", "CIT",
                                      "Heure d'\u00e9t\u00e9 d'Indon\u00e9sie centrale", "CIST"};
         String CLT[] = new String[] {"Heure du Chili", "CLT",
@@ -153,6 +155,8 @@
                                           "heure avanc\u00e9e des Pitcairn", "PDT"};
         String PKT[] = new String[] {"Heure du Pakistan", "PKT",
                                      "Heure d'\u00e9t\u00e9 du Pakistan", "PKST"} ;
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Heure normale du Pacifique", "PST",
                                      "Heure avanc\u00e9e du Pacifique", "PDT"} ;
         String RST[] = new String[] {"Heure normale de l'Est", "EST",
@@ -169,8 +173,6 @@
                                           "Heure d'\u00e9t\u00e9 d'Australie orientale (Tasmanie)", "EST"};
         String TMT[] = new String[] {"Heure du Turkm\u00e9nistan", "TMT",
                                      "Heure d'\u00e9t\u00e9 du Turkm\u00e9nistan", "TMST"} ;
-        String TRUT[] = new String[] {"Heure de Truk", "TRUT",
-                                      "Heure d'\u00e9t\u00e9 de Truk", "TRUST"};
         String ULAT[]= new String[] {"Heure de l'Ulaanbaatar", "ULAT",
                                      "Heure d'\u00e9t\u00e9 de l'Ulaanbaatar", "ULAST"} ;
         String WART[] = new String[] {"Heure D'Argentine de l'Ouest", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Heure de Davis", "DAVT",
                                                "Heure d'\u00e9t\u00e9 de Davis", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Heure de Dumont-d'Urville", "DDUT",
                                                         "Heure d'\u00e9t\u00e9 de Dumont-d'Urville", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Heure de Mawson", "MAWT",
                                                 "Heure d'\u00e9t\u00e9 de Mawson", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Heure du Vanuatu", "VUT",
                                             "Heure d'\u00e9t\u00e9 du Vanuatu", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Heure de Palaos", "PWT",
                                             "Heure d'\u00e9t\u00e9 de Palaos", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Heure de Ponap\u00e9", "PONT",
-                                             "Heure d'\u00e9t\u00e9 de Ponap\u00e9", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Heure de Papouasie-Nouvelle-Guin\u00e9e", "PGT",
                                                    "Heure d'\u00e9t\u00e9 de de Papouasie-Nouvelle-Guin\u00e9e", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Heure des \u00celes Cook", "CKT",
@@ -804,12 +811,12 @@
                                              "Heure d'\u00e9t\u00e9 de Kiribati", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Heure de Tonga", "TOT",
                                                 "Heure d'\u00e9t\u00e9 de Tonga", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Heure de Wake", "WAKT",
                                            "Heure d'\u00e9t\u00e9 de Wake", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Heure de Wallis et Futuna", "WFT",
                                              "Heure d'\u00e9t\u00e9 de Wallis et Futuna", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_it.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Ora estiva dell'Europa centrale", "CEST"};
         String CHAST[] = new String[] {"Ora di Chatham standard", "CHAST",
                                        "Ora legale di Chatham", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Ora dell'Indonesia centrale", "CIT",
                                      "Ora estiva dell'Indonesia centrale", "CIST"};
         String CLT[] = new String[] {"Ora del Cile", "CLT",
@@ -153,6 +155,8 @@
                                           "Ora legale di Pitcairn", "PDT"};
         String PKT[] = new String[] {"Ora del Pakistan", "PKT",
                                      "Ora estiva del Pakistan", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Ora solare della costa occidentale USA", "PST",
                                      "Ora legale della costa occidentale USA", "PDT"};
         String RST[] = new String[] {"Ora solare USA orientale", "EST",
@@ -169,8 +173,6 @@
                                           "Ora estiva orientale (Tasmania)", "EST"};
         String TMT[] = new String[] {"Ora del Turkmenistan", "TMT",
                                      "Ora estiva del Turkmenistan", "TMST"};
-        String TRUT[] = new String[] {"Ora di Truk", "TRUT",
-                                      "Ora estiva di Truk", "TRUST"};
         String ULAT[]= new String[] {"Ora di Ulaanbaatar", "ULAT",
                                      "Ora estiva di Ulaanbaatar", "ULAST"};
         String WART[] = new String[] {"Ora dell'Argentina occidentale", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Ora di Davis", "DAVT",
                                                "Ora estiva di Davis", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Ora di Dumont-d'Urville", "DDUT",
                                                         "Ora estiva di Dumont-d'Urville", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Ora di Mawson", "MAWT",
                                                 "Ora estiva di Mawson", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Ora di Vanuatu", "VUT",
                                             "Ora estiva di Vanuatu", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Ora di Palau", "PWT",
                                             "Ora estiva di Palau", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ora di Ponape", "PONT",
-                                             "Ora estiva di Ponape", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Ora di Papua Nuova Guinea", "PGT",
                                                    "Ora estiva di Papua Nuova Guinea", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Ora delle Isole Cook", "CKT",
@@ -804,12 +811,12 @@
                                              "Ora estiva delle Isole Gilbert", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Ora di Tonga", "TOT",
                                                 "Ora estiva di Tonga", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Ora di Wake", "WAKT",
                                            "Ora estiva di Wake", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Ora di Wallis e Futuna", "WFT",
                                              "Ora estiva di Wallis e Futuna", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ja.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "CEST"};
         String CHAST[] = new String[] {"\u30c1\u30e3\u30bf\u30e0\u6a19\u6e96\u6642", "CHAST",
                                        "\u30c1\u30e3\u30bf\u30e0\u590f\u6642\u9593", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u6642\u9593", "CIT",
                                      "\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u590f\u6642\u9593", "CIST"};
         String CLT[] = new String[] {"\u30c1\u30ea\u6642\u9593", "CLT",
@@ -153,6 +155,8 @@
                                           "\u30d4\u30c8\u30b1\u30eb\u30f3\u5cf6\u590f\u6642\u9593", "PDT"};
         String PKT[] = new String[] {"\u30d1\u30ad\u30b9\u30bf\u30f3\u6642\u9593", "PKT",
                                      "\u30d1\u30ad\u30b9\u30bf\u30f3\u590f\u6642\u9593", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642", "PST",
                                      "\u592a\u5e73\u6d0b\u590f\u6642\u9593", "PDT"};
         String RST[] = new String[] {"\u6771\u90e8\u6a19\u6e96\u6642", "EST",
@@ -169,8 +173,6 @@
                                           "\u6771\u90e8\u590f\u6642\u9593 (\u30bf\u30b9\u30de\u30cb\u30a2)", "EST"};
         String TMT[] = new String[] {"\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u6642\u9593", "TMT",
                                      "\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u590f\u6642\u9593", "TMST"};
-        String TRUT[] = new String[] {"\u30c8\u30e9\u30c3\u30af\u6642\u9593", "TRUT",
-                                      "\u30c8\u30e9\u30c3\u30af\u590f\u6642\u9593", "TRUST"};
         String ULAT[]= new String[] {"\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u6642\u9593", "ULAT",
                                      "\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u590f\u6642\u9593", "ULAST"};
         String WART[] = new String[] {"\u897f\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3\u6642\u9593", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"\u30c7\u30a4\u30d3\u30b9\u6642\u9593", "DAVT",
                                                "\u30c7\u30a4\u30d3\u30b9\u590f\u6642\u9593", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u6642\u9593", "DDUT",
                                                         "\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u590f\u6642\u9593", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\u30e2\u30fc\u30bd\u30f3\u6642\u9593", "MAWT",
                                                 "\u30e2\u30fc\u30bd\u30f3\u590f\u6642\u9593", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\u30d0\u30cc\u30a2\u30c4\u6642\u9593", "VUT",
                                             "\u30d0\u30cc\u30a2\u30c4\u590f\u6642\u9593", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"\u30d1\u30e9\u30aa\u6642\u9593", "PWT",
                                             "\u30d1\u30e9\u30aa\u590f\u6642\u9593", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"\u30dd\u30ca\u30da\u6642\u9593", "PONT",
-                                             "\u30dd\u30ca\u30da\u590f\u6642\u9593", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u6642\u9593", "PGT",
                                                    "\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u590f\u6642\u9593", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\u30af\u30c3\u30af\u8af8\u5cf6\u6642\u9593", "CKT",
@@ -804,12 +811,12 @@
                                              "\u30ae\u30eb\u30d0\u30fc\u30c8\u8af8\u5cf6\u590f\u6642\u9593", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\u30c8\u30f3\u30ac\u6642\u9593", "TOT",
                                                 "\u30c8\u30f3\u30ac\u590f\u6642\u9593", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\u30a6\u30a7\u30fc\u30af\u6642\u9593", "WAKT",
                                            "\u30a6\u30a7\u30fc\u30af\u590f\u6642\u9593", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u6642\u9593", "WFT",
                                              "\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u590f\u6642\u9593", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_ko.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\uc911\uc559 \uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CEST"};
         String CHAST[] = new String[] {"Chatham \ud45c\uc900\uc2dc", "CHAST",
                                        "Chatham \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc2dc\uac04", "CIT",
                                      "\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CIST"};
         String CLT[] = new String[] {"\uce60\ub808 \uc2dc\uac04", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT"};
         String PKT[] = new String[] {"\ud30c\ud0a4\uc2a4\ud0c4 \uc2dc\uac04", "PKT",
                                      "\ud30c\ud0a4\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\ud0dc\ud3c9\uc591 \ud45c\uc900\uc2dc", "PST",
                                      "\ud0dc\ud3c9\uc591 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT"};
         String RST[] = new String[] {"\ub3d9\ubd80 \ud45c\uc900\uc2dc", "EST",
@@ -169,8 +173,6 @@
                                           "\ub3d9\ubd80 \uc77c\uad11\uc808\uc57d\uc2dc\uac04(\ud0dc\uc988\uba54\uc774\ub2c8\uc544)", "EST"};
         String TMT[] = new String[] {"\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc2dc\uac04", "TMT",
                                      "\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TMST"};
-        String TRUT[] = new String[] {"\ud2b8\ub8e8\ud06c \uc2dc\uac04", "TRUT",
-                                      "\ud2b8\ub8e8\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TRUST"};
         String ULAT[]= new String[] {"\uc6b8\ub780\ubc14\ud0c0\ub974 \uc2dc\uac04", "ULAT",
                                      "\uc6b8\ub780\ubc14\ud0c0\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ULAST"};
         String WART[] = new String[] {"\uc11c\ubd80 \uc544\ub974\ud5e8\ud2f0\ub098 \uc2dc\uac04", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Davis \uc2dc\uac04", "DAVT",
                                                "Davis \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"\ub4a4\ubabd \ub4a4\ub974\ube4c \uc2dc\uac04", "DDUT",
                                                         "\ub4a4\ubabd \ub4a4\ub974\ube4c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\ubaa8\uc2a8 \uc2dc\uac04", "MAWT",
                                                 "\ubaa8\uc2a8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\ube44\ub204\uc544\ud22c \uc2dc\uac04", "VUT",
                                             "\ubc14\ub204\uc544\ud22c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"\ud314\ub77c\uc6b0 \uc2dc\uac04", "PWT",
                                             "\ud314\ub77c\uc6b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"\ud3ec\ub098\ud504 \uc2dc\uac04", "PONT",
-                                            "\ud3ec\ub098\ud504 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc2dc\uac04", "PGT",
                                                   "\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\ucfe0\ud06c \uad70\ub3c4 \uc2dc\uac04", "CKT",
@@ -804,12 +811,12 @@
                                              "\uae38\ubc84\ud2b8 \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\ud1b5\uac00 \uc2dc\uac04", "TOT",
                                                 "\ud1b5\uac00 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\uc6e8\uc774\ud06c \uc2dc\uac04", "WAKT",
                                            "\uc6e8\uc774\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\uc6d4\ub9ac\uc2a4 \ud6c4\ud22c\ub098 \uc2dc\uac04", "WFT",
                                              "\uc6d4\ub9ac\uc2a4 \ud6c4\ud2b8\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_sv.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "Centraleuropeisk sommartid", "CEST"};
         String CHAST[] = new String[] {"Chatham, normaltid", "CHAST",
                                        "Chatham, sommartid", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"Centralindonesisk tid", "CIT",
                                      "Centralindonesisk sommartid", "CIST"};
         String CLT[] = new String[] {"Chile, normaltid", "CLT",
@@ -153,6 +155,8 @@
                                           "Pitcairn, sommartid", "PDT"};
         String PKT[] = new String[] {"Pakistan, normaltid", "PKT",
                                      "Pakistan, sommartid", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"Stilla havet, normaltid", "PST",
                                      "Stilla havet, sommartid", "PDT"};
         String RST[] = new String[] {"Eastern, normaltid", "EST",
@@ -169,8 +173,6 @@
                                           "Eastern, sommartid (Tasmanien)", "EST"};
         String TMT[] = new String[] {"Turkmenistan, normaltid", "TMT",
                                      "Turkmenistan, sommartid", "TMST"};
-        String TRUT[] = new String[] {"Truk, normaltid", "TRUT",
-                                      "Truk, sommartid", "TRUST"};
         String ULAT[]= new String[] {"Ulaanbaatar, normaltid", "ULAT",
                                      "Ulaanbaatar, sommartid", "ULAST"};
         String WART[] = new String[] {"V\u00e4stargentina, normaltid", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"Davis, normaltid", "DAVT",
                                                "Davis, sommartid", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville, normaltid", "DDUT",
                                                         "Dumont-d'Urville, sommartid", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"Mawson, normaltid", "MAWT",
                                                 "Mawson, sommartid", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"Vanuatu, normaltid", "VUT",
                                             "Vanuatu, sommartid", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"Palau, normaltid", "PWT",
                                             "Palau, sommartid", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape, normaltid", "PONT",
-                                             "Ponape, sommartid", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"Papua Nya Guinea, normaltid", "PGT",
                                                    "Papua Nya Guinea, sommartid", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"Cook\u00f6arna, normaltid", "CKT",
@@ -804,12 +811,12 @@
                                              "Gilbert\u00f6arna, sommartid", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"Tonga, normaltid", "TOT",
                                                 "Tonga, sommartid", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"Wake, normaltid", "WAKT",
                                            "Wake, sommartid", "WAKST"}},
             {"Pacific/Wallis", new String[] {"Wallis & Futuna, normaltid", "WFT",
                                              "Wallis & Futuna, sommartid", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\u4e2d\u6b27\u590f\u4ee4\u65f6", "CEST"};
         String CHAST[] = new String[] {"\u67e5\u8428\u59c6\u6807\u51c6\u65f6\u95f4", "CHAST",
                                        "\u67e5\u8428\u59c6\u590f\u4ee4\u65f6", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u65f6\u95f4", "CIT",
                                      "\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u590f\u4ee4\u65f6", "CIST"};
         String CLT[] = new String[] {"\u667a\u5229\u65f6\u95f4", "CLT",
@@ -153,6 +155,8 @@
                                           "\u76ae\u7279\u5eb7\u5c9b\u590f\u4ee4\u65f6", "PDT"};
         String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u65f6\u95f4", "PKT",
                                      "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u65f6", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4", "PST",
                                      "\u592a\u5e73\u6d0b\u590f\u4ee4\u65f6", "PDT"};
         String RST[] = new String[] {"\u4e1c\u90e8\u6807\u51c6\u65f6\u95f4", "EST",
@@ -169,8 +173,6 @@
                                           "\u4e1c\u90e8\u590f\u4ee4\u65f6\uff08\u5854\u65af\u9a6c\u5c3c\u4e9a\uff09", "EST"};
         String TMT[] = new String[] {"\u571f\u5e93\u66fc\u65f6\u95f4", "TMT",
                                      "\u571f\u5e93\u66fc\u590f\u4ee4\u65f6", "TMST"};
-        String TRUT[] = new String[] {"\u7279\u9c81\u514b\u65f6\u95f4", "TRUT",
-                                      "\u7279\u9c81\u514b\u590f\u4ee4\u65f6", "TRUST"};
         String ULAT[]= new String[] {"\u5e93\u4f26\u65f6\u95f4", "ULAT",
                                      "\u5e93\u4f26\u590f\u4ee4\u65f6", "ULAST"};
         String WART[] = new String[] {"\u897f\u963f\u6839\u5ef7\u65f6\u95f4", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"\u6234\u7ef4\u65af\u65f6\u95f4", "DAVT",
                                                "\u6234\u7ef4\u65af\u590f\u4ee4\u65f6", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u65f6\u95f4", "DDUT",
                                                         "Dumont-d'Urville \u590f\u4ee4\u65f6", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u65f6\u95f4", "MAWT",
                                                 "\u83ab\u68ee\u590f\u4ee4\u65f6", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -752,6 +758,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u56fe\u65f6\u95f4", "VUT",
                                             "\u74e6\u5974\u963f\u56fe\u590f\u4ee4\u65f6", "VUST"}},
@@ -790,8 +797,8 @@
             {"Pacific/Palau", new String[] {"\u5e1b\u7409\u65f6\u95f4", "PWT",
                                             "\u5e1b\u7409\u590f\u4ee4\u65f6", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape \u65f6\u95f4", "PONT",
-                                             "Ponape \u590f\u4ee4\u65f6", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u65f6\u95f4", "PGT",
                                                    "\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u590f\u4ee4\u65f6", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\u5e93\u514b\u7fa4\u5c9b\u65f6\u95f4", "CKT",
@@ -804,12 +811,12 @@
                                              "\u5409\u4f2f\u7279\u7fa4\u5c9b\u590f\u4ee4\u65f6", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\u4e1c\u52a0\u65f6\u95f4", "TOT",
                                                 "\u4e1c\u52a0\u590f\u4ee4\u65f6", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\u5a01\u514b\u65f6\u95f4", "WAKT",
                                            "\u5a01\u514b\u590f\u4ee4\u65f6", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u65f6\u95f4", "WFT",
                                              "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u590f\u4ee4\u65f6", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@
                                      "\u4e2d\u6b50\u590f\u4ee4\u6642\u9593", "CEST"};
         String CHAST[] = new String[] {"\u67e5\u5766\u6a19\u6e96\u6642\u9593", "CHAST",
                                        "\u67e5\u5766\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CHADT"};
+        String CHUT[] = new String[] {"Chuuk Time", "CHUT",
+                                      "Chuuk Summer Time", "CHUST"};
         String CIT[] = new String[] {"\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u6642\u9593", "CIT",
                                      "\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "CIST"};
         String CLT[] = new String[] {"\u667a\u5229\u6642\u9593", "CLT",
@@ -153,6 +155,8 @@
                                         "\u76ae\u7279\u5eb7\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT"};
         String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u6642\u9593", "PKT",
                                      "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u6642\u9593", "PKST"};
+        String PONT[] = new String[] {"Pohnpei Time", "PONT",
+                                      "Pohnpei Summer Time", "PONST"};
         String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642\u9593", "PST",
                                      "\u592a\u5e73\u6d0b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT"};
         String RST[] = new String[] {"\u6771\u65b9\u6a19\u6e96\u6642\u9593", "EST",
@@ -169,8 +173,6 @@
                                           "\u6771\u90e8\u590f\u4ee4\u6642\u9593 (\u5854\u65af\u6885\u5c3c\u4e9e\u5cf6)", "EST"};
         String TMT[] = new String[] {"\u571f\u5eab\u66fc\u6642\u9593", "TMT",
                                      "\u571f\u5eab\u66fc\u590f\u4ee4\u6642\u9593", "TMST"};
-        String TRUT[] = new String[] {"\u7279\u9b6f\u514b\u6642\u9593", "TRUT",
-                                      "\u7279\u9b6f\u514b\u590f\u4ee4\u6642\u9593", "TRUST"};
         String ULAT[]= new String[] {"\u5eab\u502b\u6642\u9593", "ULAT",
                                      "\u5eab\u502b\u590f\u4ee4\u6642\u9593", "ULAST"};
           String WART[] = new String[] {"\u897f\u963f\u6839\u5ef7\u6642\u9593", "WART",
@@ -309,6 +311,7 @@
             {"America/Atikokan", EST},
             {"America/Atka", HAST},
             {"America/Bahia", BRT},
+            {"America/Bahia_Banderas", CST},
             {"America/Barbados", AST},
             {"America/Belem", BRT},
             {"America/Belize", CST},
@@ -446,10 +449,13 @@
             {"America/Winnipeg", CST},
             {"America/Yakutat", AKST},
             {"America/Yellowknife", MST},
+            {"Antarctica/Casey", WST_AUS},
             {"Antarctica/Davis", new String[] {"\u81fa\u7dad\u65af\u6642\u9593", "DAVT",
                                                "\u81fa\u7dad\u65af\u590f\u4ee4\u6642\u9593", "DAVST"}},
             {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u6642\u9593", "DDUT",
                                                         "Dumont-d'Urville \u590f\u4ee4\u6642\u9593", "DDUST"}},
+            {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
+                                                   "Macquarie Island Summer Time", "MIST"}},
             {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u6642\u9593", "MAWT",
                                                 "\u83ab\u68ee\u590f\u4ee4\u6642\u9593", "MAWST"}},
             {"Antarctica/McMurdo", NZST},
@@ -753,6 +759,7 @@
             {"Pacific/Apia", WST_SAMOA},
             {"Pacific/Auckland", NZST},
             {"Pacific/Chatham", CHAST},
+            {"Pacific/Chuuk", CHUT},
             {"Pacific/Easter", EASTER},
             {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u5716\u6642\u9593", "VUT",
                                             "\u74e6\u5974\u963f\u5716\u590f\u4ee4\u6642\u9593", "VUST"}},
@@ -791,8 +798,8 @@
             {"Pacific/Palau", new String[] {"\u5e1b\u7409\u6642\u9593", "PWT",
                                             "\u5e1b\u7409\u590f\u4ee4\u6642\u9593", "PWST"}},
             {"Pacific/Pitcairn", PITCAIRN},
-            {"Pacific/Ponape", new String[] {"Ponape \u6642\u9593", "PONT",
-                                             "Ponape \u590f\u4ee4\u6642\u9593", "PONST"}},
+            {"Pacific/Pohnpei", PONT},
+            {"Pacific/Ponape", PONT},
             {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u6642\u9593", "PGT",
                                                    "\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u590f\u4ee4\u6642\u9593", "PGST"}},
             {"Pacific/Rarotonga", new String[] {"\u5eab\u514b\u7fa4\u5cf6\u6642\u9593", "CKT",
@@ -805,12 +812,12 @@
                                              "\u5409\u4f2f\u7279\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "GILST"}},
             {"Pacific/Tongatapu", new String[] {"\u6771\u52a0\u6642\u9593", "TOT",
                                                 "\u6771\u52a0\u590f\u4ee4\u6642\u9593", "TOST"}},
-            {"Pacific/Truk", TRUT},
+            {"Pacific/Truk", CHUT},
             {"Pacific/Wake", new String[] {"\u5a01\u514b\u6642\u9593", "WAKT",
                                            "\u5a01\u514b\u590f\u4ee4\u6642\u9593", "WAKST"}},
             {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u6642\u9593", "WFT",
                                              "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "WFST"}},
-            {"Pacific/Yap", TRUT},
+            {"Pacific/Yap", CHUT},
             {"Poland", CET},
             {"PRC", CTT},
             {"PST8PDT", PST},
--- a/jdk/src/share/lib/security/java.security-solaris	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/lib/security/java.security-solaris	Thu Sep 02 12:17:21 2010 -0700
@@ -260,3 +260,30 @@
 # Example,
 #   ocsp.responderCertSerialNumber=2A:FF:00
  
+#
+# Policy for failed Kerberos KDC lookups:
+#
+# When a KDC is unavailable (network error, service failure, etc), it is
+# put inside a blacklist and accessed less often for future requests. The
+# value (case-insensitive) for this policy can be:
+#
+# tryLast
+#    KDCs in the blacklist are always tried after those not on the list.
+#
+# tryLess[:max_retries,timeout]
+#    KDCs in the blacklist are still tried by their order in the configuration,
+#    but with smaller max_retries and timeout values. max_retries and timeout
+#    are optional numerical parameters (default 1 and 5000, which means once
+#    and 5 seconds). Please notes that if any of the values defined here is
+#    more than what is defined in krb5.conf, it will be ignored.
+#
+# Whenever a KDC is detected as available, it is removed from the blacklist.
+# The blacklist is reset when krb5.conf is reloaded. You can add
+# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
+# reloaded whenever a JAAS authentication is attempted.
+#
+# Example,
+#   krb5.kdc.bad.policy = tryLast
+#   krb5.kdc.bad.policy = tryLess:2,2000
+krb5.kdc.bad.policy = tryLast
+
--- a/jdk/src/share/lib/security/java.security-windows	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/lib/security/java.security-windows	Thu Sep 02 12:17:21 2010 -0700
@@ -260,3 +260,30 @@
 # Example,
 #   ocsp.responderCertSerialNumber=2A:FF:00
  
+#
+# Policy for failed Kerberos KDC lookups:
+#
+# When a KDC is unavailable (network error, service failure, etc), it is
+# put inside a blacklist and accessed less often for future requests. The
+# value (case-insensitive) for this policy can be:
+#
+# tryLast
+#    KDCs in the blacklist are always tried after those not on the list.
+#
+# tryLess[:max_retries,timeout]
+#    KDCs in the blacklist are still tried by their order in the configuration,
+#    but with smaller max_retries and timeout values. max_retries and timeout
+#    are optional numerical parameters (default 1 and 5000, which means once
+#    and 5 seconds). Please notes that if any of the values defined here is
+#    more than what is defined in krb5.conf, it will be ignored.
+#
+# Whenever a KDC is detected as available, it is removed from the blacklist.
+# The blacklist is reset when krb5.conf is reloaded. You can add
+# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
+# reloaded whenever a JAAS authentication is attempted.
+#
+# Example,
+#   krb5.kdc.bad.policy = tryLast
+#   krb5.kdc.bad.policy = tryLess:2,2000
+krb5.kdc.bad.policy = tryLast
+
--- a/jdk/src/share/native/common/check_code.c	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/share/native/common/check_code.c	Thu Sep 02 12:17:21 2010 -0700
@@ -2730,7 +2730,10 @@
                                                                 operand);
             const char *result_signature;
             check_and_push(context, signature, VM_STRING_UTF);
-            result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC) + 1;
+            result_signature = strchr(signature, JVM_SIGNATURE_ENDFUNC);
+            if (result_signature++ == NULL) {
+                CCerror(context, "Illegal signature %s", signature);
+            }
             if (result_signature[0] == JVM_SIGNATURE_VOID) {
                 stack_results = "";
             } else {
@@ -3654,14 +3657,13 @@
                        const char **signature_p, fullinfo_type *full_info_p)
 {
     const char *p = *signature_p;
-    fullinfo_type full_info = MAKE_FULLINFO(0, 0, 0);
+    fullinfo_type full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
     char result;
     int array_depth = 0;
 
     for (;;) {
         switch(*p++) {
             default:
-                full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
                 result = 0;
                 break;
 
@@ -3714,7 +3716,14 @@
                 char buffer_space[256];
                 char *buffer = buffer_space;
                 char *finish = strchr(p, JVM_SIGNATURE_ENDCLASS);
-                int length = finish - p;
+                int length;
+                if (finish == NULL) {
+                    /* Signature must have ';' after the class name.
+                     * If it does not, return 0 and ITEM_Bogus in full_info. */
+                    result = 0;
+                    break;
+                }
+                length = finish - p;
                 if (length + 1 > (int)sizeof(buffer_space)) {
                     buffer = malloc(length + 1);
                     check_and_push(context, buffer, VM_MALLOC_BLK);
--- a/jdk/src/solaris/classes/java/io/UnixFileSystem.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/solaris/classes/java/io/UnixFileSystem.java	Thu Sep 02 12:17:21 2010 -0700
@@ -187,7 +187,6 @@
                     }
                 }
             }
-            assert canonicalize0(path).equals(res) || path.startsWith(javaHome);
             return res;
         }
     }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1141,6 +1141,13 @@
             }
             result = result.resolve(element);
         }
+
+        // check file exists (without following links)
+        try {
+            UnixFileAttributes.get(result, false);
+        } catch (UnixException x) {
+            x.rethrowAsIOException(result);
+        }
         return result;
     }
 
--- a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Thu Sep 02 12:17:21 2010 -0700
@@ -1052,30 +1052,38 @@
 Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
                                                            jobject this) {
     jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    int fd;
-
-    int t = 1;
+    int fd, t = 1;
+#ifdef AF_INET6
+    int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+    int domain = AF_INET;
+#endif
 
     if (IS_NULL(fdObj)) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Socket closed");
         return;
-    } else {
-#ifdef AF_INET6
-        if (ipv6_available()) {
-            fd =  JVM_Socket(AF_INET6, SOCK_DGRAM, 0);
-        } else
-#endif /* AF_INET6 */
-            {
-                fd =  JVM_Socket(AF_INET, SOCK_DGRAM, 0);
-            }
     }
-    if (fd == JVM_IO_ERR) {
+
+    if ((fd = JVM_Socket(domain, SOCK_DGRAM, 0)) == JVM_IO_ERR) {
         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                        "Error creating socket");
         return;
     }
 
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        int arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+            close(fd);
+            return;
+        }
+    }
+#endif /* AF_INET6 */
+
      setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
 
 #ifdef __linux__
@@ -1088,7 +1096,7 @@
      * On Linux for IPv6 sockets we must set the hop limit
      * to 1 to be compatible with default ttl of 1 for IPv4 sockets.
      */
-    if (ipv6_available()) {
+    if (domain == AF_INET6) {
         int ttl = 1;
         setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,
                    sizeof(ttl));
--- a/jdk/src/solaris/native/java/net/PlainSocketImpl.c	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/solaris/native/java/net/PlainSocketImpl.c	Thu Sep 02 12:17:21 2010 -0700
@@ -181,6 +181,12 @@
                                            jboolean stream) {
     jobject fdObj, ssObj;
     int fd;
+    int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
+#ifdef AF_INET6
+    int domain = ipv6_available() ? AF_INET6 : AF_INET;
+#else
+    int domain = AF_INET;
+#endif
 
     if (socketExceptionCls == NULL) {
         jclass c = (*env)->FindClass(env, "java/net/SocketException");
@@ -194,25 +200,29 @@
         (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
         return;
     }
-#ifdef AF_INET6
-    if (ipv6_available()) {
-        fd = JVM_Socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
-    } else
-#endif /* AF_INET6 */
-        {
-            fd = JVM_Socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
-        }
-    if (fd == JVM_IO_ERR) {
+
+    if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) {
         /* note: if you run out of fds, you may not be able to load
          * the exception class, and get a NoClassDefFoundError
          * instead.
          */
         NET_ThrowNew(env, errno, "can't create socket");
         return;
-    } else {
-        (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
     }
 
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        int arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
+            close(fd);
+            return;
+        }
+    }
+#endif /* AF_INET6 */
+
     /*
      * If this is a server socket then enable SO_REUSEADDR
      * automatically and set to non blocking.
@@ -221,9 +231,15 @@
     if (ssObj != NULL) {
         int arg = 1;
         SET_NONBLOCKING(fd);
-        JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
-            sizeof(arg));
+        if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
+                           sizeof(arg)) < 0) {
+            NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
+            close(fd);
+            return;
+        }
     }
+
+    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
 }
 
 /*
--- a/jdk/src/solaris/native/sun/nio/ch/Net.c	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/solaris/native/sun/nio/ch/Net.c	Thu Sep 02 12:17:21 2010 -0700
@@ -170,6 +170,22 @@
     if (fd < 0) {
         return handleSocketError(env, errno);
     }
+
+#ifdef AF_INET6
+    /* Disable IPV6_V6ONLY to ensure dual-socket support */
+    if (domain == AF_INET6) {
+        int arg = 0;
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
+                       sizeof(int)) < 0) {
+            JNU_ThrowByNameWithLastError(env,
+                                         JNU_JAVANETPKG "SocketException",
+                                         "sun.nio.ch.Net.setIntOption");
+            close(fd);
+            return -1;
+        }
+    }
+#endif
+
     if (reuse) {
         int arg = 1;
         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
--- a/jdk/src/windows/classes/java/io/Win32FileSystem.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/src/windows/classes/java/io/Win32FileSystem.java	Thu Sep 02 12:17:21 2010 -0700
@@ -424,7 +424,6 @@
                     }
                 }
             }
-            assert canonicalize0(path).equalsIgnoreCase(res);
             return res;
         }
     }
--- a/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh	Thu Sep 02 12:17:21 2010 -0700
@@ -55,7 +55,7 @@
   Linux )
     FS="/"
     ;;
-  Windows* )
+  Windows* | CYGWIN* )
     FS="\\"
     ;;
 esac
--- a/jdk/test/java/net/URI/Test.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/java/net/URI/Test.java	Thu Sep 02 12:17:21 2010 -0700
@@ -1536,6 +1536,7 @@
         serial();
         urls();
         npes();
+        bugs();
     }
 
 
@@ -1572,6 +1573,19 @@
     }
 
 
+    // miscellaneous bugs/rfes that don't fit in with the test framework
+
+    static void bugs() {
+        // 6339649 - include detail message from nested exception
+        try {
+            URI uri = URI.create("http://nowhere.net/should not be permitted");
+        } catch (IllegalArgumentException e) {
+            if ("".equals(e.getMessage()) || e.getMessage() == null) {
+                throw new RuntimeException ("No detail message");
+            }
+        }
+    }
+
     public static void main(String[] args) throws Exception {
         switch (args.length) {
 
--- a/jdk/test/java/nio/file/Path/Misc.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/java/nio/file/Path/Misc.java	Thu Sep 02 12:17:21 2010 -0700
@@ -261,6 +261,21 @@
         assertTrue(file.toRealPath(true).isSameFile(file.toRealPath(false)));
 
         /**
+         * Test: toRealPath should fail if file does not exist
+         */
+        Path doesNotExist = dir.resolve("DoesNotExist");
+        try {
+            doesNotExist.toRealPath(true);
+            throw new RuntimeException("IOException expected");
+        } catch (IOException expected) {
+        }
+        try {
+            doesNotExist.toRealPath(false);
+            throw new RuntimeException("IOException expected");
+        } catch (IOException expected) {
+        }
+
+        /**
          * Test: toRealPath(true) should resolve links
          */
         if (supportsLinks) {
--- a/jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh	Thu Sep 02 12:17:21 2010 -0700
@@ -23,6 +23,7 @@
 
 #
 # @test
+# @ignore until 6543856 is fixed
 # @bug 4990825
 # @summary attach to external but local JVM processes
 # @library ../../testlibrary
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/file/DirPermissionDenied.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.io.IOException;
+
+public class DirPermissionDenied {
+    public static void main(String[] args) throws Exception {
+        URL url = new URL("file:" + args[0]);
+
+        try {
+            URLConnection uc = url.openConnection();
+            uc.connect();
+        } catch (IOException e) {
+            // OK
+        } catch (Exception e) {
+            throw new RuntimeException("Failed " + e);
+        }
+
+        try {
+            URLConnection uc = url.openConnection();
+            uc.getInputStream();
+        } catch (IOException e) {
+            // OK
+        } catch (Exception e) {
+            throw new RuntimeException("Failed " + e);
+        }
+
+        try {
+            URLConnection uc = url.openConnection();
+            uc.getContentLengthLong();
+        } catch (IOException e) {
+            // OK
+        } catch (Exception e) {
+            throw new RuntimeException("Failed " + e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/file/DirPermissionDenied.sh	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# @test
+# @bug 6977851
+# @summary NPE from FileURLConnection.connect
+# @build DirPermissionDenied
+# @run shell DirPermissionDenied.sh
+
+TESTDIR="${TESTCLASSES}/DirPermissionDeniedDirectory"
+echo ${TESTDIR}
+
+rm -rf ${TESTDIR}
+mkdir -p ${TESTDIR}
+chmod 333 ${TESTDIR}
+
+$TESTJAVA/bin/java -classpath $TESTCLASSES DirPermissionDenied ${TESTDIR}
+result=$?
+rm -rf ${TESTDIR}
+exit $result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/BadKdcDefaultValue.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 6976536
+ * @summary Solaris JREs do not have the krb5.kdc.bad.policy configured by default.
+ * @run main/othervm BadKdcDefaultValue
+ */
+
+import java.security.Security;
+
+public class BadKdcDefaultValue {
+    public static void main(String[] args) throws Exception {
+        if (!"tryLast".equalsIgnoreCase(
+                Security.getProperty("krb5.kdc.bad.policy"))) {
+            throw new Exception("Default value not correct");
+        }
+    }
+}
+
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java	Thu Sep 02 12:17:21 2010 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6226610
+ * @bug 6226610 6973030
  * @run main/othervm B6226610
  * @summary HTTP tunnel connections send user headers to proxy
  */
@@ -36,45 +36,23 @@
 
 import java.io.*;
 import java.net.*;
-import javax.net.ssl.*;
-import javax.net.ServerSocketFactory;
-import sun.net.www.*;
-import java.util.Enumeration;
+import sun.net.www.MessageHeader;
 
 public class B6226610 {
     static HeaderCheckerProxyTunnelServer proxy;
 
-    // it seems there's no proxy ever if a url points to 'localhost',
-    // even if proxy related properties are set. so we need to bind
-    // our simple http proxy and http server to a non-loopback address
-    static InetAddress firstNonLoAddress = null;
-
-    public static void main(String[] args)
+    public static void main(String[] args) throws Exception
     {
-       try {
-          proxy = new HeaderCheckerProxyTunnelServer();
-          proxy.start();
-       } catch (Exception e) {
-          System.out.println("Cannot create proxy: " + e);
-       }
+        proxy = new HeaderCheckerProxyTunnelServer();
+        proxy.start();
 
-       try {
-            firstNonLoAddress = getNonLoAddress();
-
-            if (firstNonLoAddress == null) {
-                System.out.println("The test needs at least one non-loopback address to run. Quit now.");
-                System.exit(0);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        System.setProperty( "https.proxyHost", firstNonLoAddress.getHostAddress());
-        System.setProperty( "https.proxyPort", (new Integer(proxy.getLocalPort())).toString() );
+        String hostname = InetAddress.getLocalHost().getHostName();
 
         try {
-           URL u = new URL("https://" + firstNonLoAddress.getHostAddress());
-           java.net.URLConnection c = u.openConnection();
+           URL u = new URL("https://" + hostname + "/");
+           System.out.println("Connecting to " + u);
+           InetSocketAddress proxyAddr = new InetSocketAddress(hostname, proxy.getLocalPort());
+           java.net.URLConnection c = u.openConnection(new Proxy(Proxy.Type.HTTP, proxyAddr));
 
            /* I want this header to go to the destination server only, protected
             * by SSL
@@ -89,33 +67,15 @@
             }
             else
                System.out.println(e);
-
+         } finally {
+             if (proxy != null) proxy.shutdown();
          }
 
          if (HeaderCheckerProxyTunnelServer.failed)
-            throw new RuntimeException("Test failed: Proxy should not receive user defined headers for tunneled requests");
+            throw new RuntimeException("Test failed; see output");
     }
-
-    public static InetAddress getNonLoAddress() throws Exception {
-        NetworkInterface loNIC = NetworkInterface.getByInetAddress(InetAddress.getByName("localhost"));
-        Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
-        while (nics.hasMoreElements()) {
-            NetworkInterface nic = nics.nextElement();
-            if (!nic.getName().equalsIgnoreCase(loNIC.getName())) {
-                Enumeration<InetAddress> addrs = nic.getInetAddresses();
-                while (addrs.hasMoreElements()) {
-                    InetAddress addr = addrs.nextElement();
-                    if (!addr.isLoopbackAddress())
-                        return addr;
-                }
-            }
-        }
-        return null;
-    }
-
 }
 
-
 class HeaderCheckerProxyTunnelServer extends Thread
 {
     public static boolean failed = false;
@@ -139,6 +99,10 @@
        }
     }
 
+    void shutdown() {
+        try { ss.close(); } catch (IOException e) {}
+    }
+
     public void run()
     {
         try {
@@ -178,6 +142,15 @@
            retrieveConnectInfo(statusLine);
 
            if (mheader.findValue("X-TestHeader") != null) {
+             System.out.println("Proxy should not receive user defined headers for tunneled requests");
+             failed = true;
+           }
+
+           // 6973030
+           String value;
+           if ((value = mheader.findValue("Proxy-Connection")) == null ||
+                !value.equals("keep-alive")) {
+             System.out.println("Proxy-Connection:keep-alive not being sent");
              failed = true;
            }
 
--- a/jdk/test/tools/jar/JarEntryTime.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/tools/jar/JarEntryTime.java	Thu Sep 02 12:17:21 2010 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4225317
+ * @bug 4225317 6969651
  * @summary Check extracted files have date as per those in the .jar file
  */
 
@@ -68,17 +68,9 @@
     }
 
     public static void realMain(String[] args) throws Throwable {
-        final long now = System.currentTimeMillis();
-        final long earlier = now - (60L * 60L * 6L * 1000L);
-        final long yesterday = now - (60L * 60L * 24L * 1000L);
-
-        // ZipEntry's mod date has 2 seconds precision: give extra time to
-        // allow for e.g. rounding/truncation and networked/samba drives.
-        final long PRECISION = 10000L;
 
         File dirOuter = new File("outer");
         File dirInner = new File(dirOuter, "inner");
-
         File jarFile = new File("JarEntryTime.jar");
 
         // Remove any leftovers from prior run
@@ -99,6 +91,17 @@
         PrintWriter pw = new PrintWriter(fileInner);
         pw.println("hello, world");
         pw.close();
+
+        // Get the "now" from the "last-modified-time" of the last file we
+        // just created, instead of the "System.currentTimeMillis()", to
+        // workaround the possible "time difference" due to nfs.
+        final long now = fileInner.lastModified();
+        final long earlier = now - (60L * 60L * 6L * 1000L);
+        final long yesterday = now - (60L * 60L * 24L * 1000L);
+        // ZipEntry's mod date has 2 seconds precision: give extra time to
+        // allow for e.g. rounding/truncation and networked/samba drives.
+        final long PRECISION = 10000L;
+
         dirOuter.setLastModified(now);
         dirInner.setLastModified(yesterday);
         fileInner.setLastModified(earlier);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/CommandLineTests.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,179 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test CommandLineTests.sh
+ * @bug  6521334 6965836 6965836
+ * @compile -XDignore.symbol.file CommandLineTests.java Pack200Test.java
+ * @run main/timeout=1200 CommandLineTests
+ * @summary An ad hoc test to verify the behavior of pack200/unpack200 CLIs,
+ *           and a simulation of pack/unpacking in the install repo.
+ * @author ksrini
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+/*
+ * We try a potpouri of things ie. we have pack.conf to setup some
+ * options as well as a couple of command line options. We also test
+ * the packing and unpacking mechanism using the Java APIs. This also
+ * simulates pack200 the install workspace, noting that this is a simulation
+ * and can only test jars that are guaranteed to be available, also the
+ * configuration may not be in sync with the installer workspace.
+ */
+
+public class CommandLineTests {
+    private static final File CWD = new File(".");
+    private static final File EXP_SDK = new File(CWD, "exp-sdk-image");
+    private static final File EXP_SDK_LIB_DIR = new File(EXP_SDK, "lib");
+    private static final File EXP_SDK_BIN_DIR = new File(EXP_SDK, "bin");
+    private static final File EXP_JRE_DIR = new File(EXP_SDK, "jre");
+    private static final File EXP_JRE_LIB_DIR = new File(EXP_JRE_DIR, "lib");
+    private static final File RtJar = new File(EXP_JRE_LIB_DIR, "rt.jar");
+    private static final File CharsetsJar = new File(EXP_JRE_LIB_DIR, "charsets.jar");
+    private static final File JsseJar = new File(EXP_JRE_LIB_DIR, "jsse.jar");
+    private static final File ToolsJar = new File(EXP_SDK_LIB_DIR, "tools.jar");
+    private static final File javaCmd;
+    private static final File javacCmd;
+    private static final File ConfigFile = new File("pack.conf");
+    private static final List<File> jarList;
+
+    static {
+        javaCmd = Utils.IsWindows
+                    ? new File(EXP_SDK_BIN_DIR, "java.exe")
+                    : new File(EXP_SDK_BIN_DIR, "java");
+
+        javacCmd = Utils.IsWindows
+                    ? new File(EXP_SDK_BIN_DIR, "javac.exe")
+                    : new File(EXP_SDK_BIN_DIR, "javac");
+
+        jarList = new ArrayList<File>();
+        jarList.add(RtJar);
+        jarList.add(CharsetsJar);
+        jarList.add(JsseJar);
+        jarList.add(ToolsJar);
+    }
+
+    // init test area with a copy of the sdk
+    static void init() throws IOException {
+            Utils.recursiveCopy(Utils.JavaSDK, EXP_SDK);
+            creatConfigFile();
+    }
+
+    // Hopefully, this should be kept in sync with what the installer does.
+    static void creatConfigFile() throws IOException {
+        FileOutputStream fos = null;
+        PrintStream ps = null;
+        try {
+            fos = new FileOutputStream(ConfigFile);
+            ps = new PrintStream(fos);
+            ps.println("com.sun.java.util.jar.pack.debug.verbose=0");
+            ps.println("pack.modification.time=keep");
+            ps.println("pack.keep.class.order=true");
+            ps.println("pack.deflate.hint=false");
+            // Fail the build, if new or unknown attributes are introduced.
+            ps.println("pack.unknown.attribute=error");
+            ps.println("pack.segment.limit=-1");
+            // BugId: 6328502,  These files will be passed-through as-is.
+            ps.println("pack.pass.file.0=java/lang/Error.class");
+            ps.println("pack.pass.file.1=java/lang/LinkageError.class");
+            ps.println("pack.pass.file.2=java/lang/Object.class");
+            ps.println("pack.pass.file.3=java/lang/Throwable.class");
+            ps.println("pack.pass.file.4=java/lang/VerifyError.class");
+            ps.println("pack.pass.file.5=com/sun/demo/jvmti/hprof/Tracker.class");
+        } finally {
+            Utils.close(ps);
+            Utils.close(fos);
+        }
+    }
+
+    static void runPack200(boolean jre) throws IOException {
+        List<String> cmdsList = new ArrayList<String>();
+        for (File f : jarList) {
+            if (jre && f.getName().equals("tools.jar")) {
+                continue;  // need not worry about tools.jar for JRE
+            }
+            // make a backup copy for re-use
+            File bakFile = new File(f.getName() + ".bak");
+            if (!bakFile.exists()) {  // backup
+                Utils.copyFile(f.getAbsoluteFile(), bakFile.getAbsoluteFile());
+            } else {  // restore
+                Utils.copyFile(bakFile.getAbsoluteFile(), f.getAbsoluteFile());
+            }
+            cmdsList.clear();
+            cmdsList.add(Utils.getPack200Cmd());
+            cmdsList.add("-J-esa");
+            cmdsList.add("-J-ea");
+            cmdsList.add(Utils.Is64Bit ? "-J-Xmx1g" : "-J-Xmx512m");
+            cmdsList.add("--repack");
+            cmdsList.add("--config-file=" + ConfigFile.getAbsolutePath());
+            if (jre) {
+                cmdsList.add("--strip-debug");
+            }
+            // NOTE: commented until 6965836 is fixed
+            // cmdsList.add("--code-attribute=StackMapTable=strip");
+            cmdsList.add(f.getAbsolutePath());
+            Utils.runExec(cmdsList);
+        }
+    }
+
+    static void testJRE() throws IOException {
+        runPack200(true);
+        // the speciment JRE
+        List<String> cmdsList = new ArrayList<String>();
+        cmdsList.add(javaCmd.getAbsolutePath());
+        cmdsList.add("-verify");
+        cmdsList.add("-version");
+        Utils.runExec(cmdsList);
+    }
+
+    static void testJDK() throws IOException {
+        runPack200(false);
+        // test the specimen JDK
+        List<String> cmdsList = new ArrayList<String>();
+        cmdsList.add(javaCmd.getAbsolutePath());
+        cmdsList.add("-verify");
+        cmdsList.add("-version");
+        Utils.runExec(cmdsList);
+
+        // invoke javac to test the tools.jar
+        cmdsList.clear();
+        cmdsList.add(javacCmd.getAbsolutePath());
+        cmdsList.add("-J-verify");
+        cmdsList.add("-help");
+        Utils.runExec(cmdsList);
+    }
+    public static void main(String... args) {
+        try {
+            init();
+            testJRE();
+            testJDK();
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/Pack200Props.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6575373 6969063
+ * @summary verify default properties of the packer/unpacker and segment limit
+ * @compile -XDignore.symbol.file Utils.java Pack200Props.java
+ * @run main Pack200Props
+ * @author ksrini
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Pack200;
+import java.util.jar.Pack200.Packer;
+
+/*
+ * Run this against a large jar file, by default the packer should generate only
+ * one segment, parse the output of the packer to verify if this is indeed true.
+ */
+
+public class Pack200Props {
+
+    public static void main(String... args) {
+        verifyDefaults();
+        File out = new File("test" + Utils.PACK_FILE_EXT);
+        out.delete();
+        verifySegmentLimit(out);
+    }
+
+    static void verifySegmentLimit(File outFile) {
+        File sdkHome = Utils.JavaSDK;
+        File testJar = new File(new File(sdkHome, "lib"), "tools.jar");
+
+        System.out.println("using pack200: " + Utils.getPack200Cmd());
+
+        List<String> cmdsList = new ArrayList<>();
+        cmdsList.add(Utils.getPack200Cmd());
+        cmdsList.add("--effort=1");
+        cmdsList.add("--verbose");
+        cmdsList.add("--no-gzip");
+        cmdsList.add(outFile.getName());
+        cmdsList.add(testJar.getAbsolutePath());
+        List<String> outList = Utils.runExec(cmdsList);
+
+        int count = 0;
+        for (String line : outList) {
+            System.out.println(line);
+            if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) {
+                count++;
+            }
+        }
+        if (count == 0) {
+            throw new RuntimeException("no segments or no output ????");
+        } else if (count > 1) {
+            throw new RuntimeException("multiple segments detected, expected 1");
+        }
+    }
+
+    private static void verifyDefaults() {
+        Map<String, String> expectedDefaults = new HashMap<>();
+        Packer p = Pack200.newPacker();
+        expectedDefaults.put("com.sun.java.util.jar.pack.default.timezone",
+                p.FALSE);
+        expectedDefaults.put("com.sun.java.util.jar.pack.disable.native",
+                p.FALSE);
+        expectedDefaults.put("com.sun.java.util.jar.pack.verbose", "0");
+        expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "CompilationID", "RUH");
+        expectedDefaults.put(p.CLASS_ATTRIBUTE_PFX + "SourceID", "RUH");
+        expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CharacterRangeTable",
+                "NH[PHPOHIIH]");
+        expectedDefaults.put(p.CODE_ATTRIBUTE_PFX + "CoverageTable",
+                "NH[PHHII]");
+        expectedDefaults.put(p.DEFLATE_HINT, p.KEEP);
+        expectedDefaults.put(p.EFFORT, "5");
+        expectedDefaults.put(p.KEEP_FILE_ORDER, p.TRUE);
+        expectedDefaults.put(p.MODIFICATION_TIME, p.KEEP);
+        expectedDefaults.put(p.SEGMENT_LIMIT, "-1");
+        expectedDefaults.put(p.UNKNOWN_ATTRIBUTE, p.PASS);
+
+        Map<String, String> props = p.properties();
+        int errors = 0;
+        for (String key : expectedDefaults.keySet()) {
+            String def = expectedDefaults.get(key);
+            String x = props.get(key);
+            if (x == null) {
+                System.out.println("Error: key not found:" + key);
+                errors++;
+            } else {
+                if (!def.equals(x)) {
+                    System.out.println("Error: key " + key
+                            + "\n  value expected: " + def
+                            + "\n  value obtained: " + x);
+                    errors++;
+                }
+            }
+        }
+        if (errors > 0) {
+            throw new RuntimeException(errors +
+                    " error(s) encountered in default properties verification");
+        }
+    }
+}
+
--- a/jdk/test/tools/pack200/Pack200Simple.sh	Tue Aug 31 15:05:09 2010 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-#
-# Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test Pack200Simple.sh
-# @bug  6521334
-# @build Pack200Test
-# @run shell/timeout=1200 Pack200Simple.sh
-# @summary An ad hoc test to verify class-file format.
-# @author Kumar Srinivasan
-
-# The goal of this test is to assist javac or other developers 
-# who modify class file formats, to quickly test those modifications
-# without having to build the install workspace. However it must
-# be noted that building the install workspace is the only know
-# way to prevent build breakages.
-
-# Pack200 developers could use this  as a basic smoke-test, however 
-# please note, there are other more elaborate and  thorough tests for 
-# this very purpose. 
-
-# We try a potpouri of things ie. we have pack.conf to setup some 
-# options as well as a couple of command line options. We also test
-# the packing and unpacking mechanism using the Java APIs.
-
-# print error and exit with a message 
-errorOut() {
-  if [ "x$1" = "x" ]; then
-    printf "Error: Unknown error\n"
-  else
-    printf "Error: %s\n" "$1"
-  fi
-
-  exit 1
-}
-
-# Verify directory context variables are set
-if [ "${TESTJAVA}" = "" ]; then
-  errorOut "TESTJAVA not set.  Test cannot execute.  Failed."
-fi
-
-if [ "${TESTSRC}" = "" ]; then
-  errorOut "TESTSRC not set.  Test cannot execute.  Failed."
-fi
-
-
-if [ "${TESTCLASSES}" = "" ]; then
-  errorOut "TESTCLASSES not set.  Test cannot execute.  Failed."
-fi
-
-# The common java utils we need
-PACK200=${TESTJAVA}/bin/pack200
-UNPACK200=${TESTJAVA}/bin/unpack200
-JAR=${TESTJAVA}/bin/jar
-
-# For Windows and Linux needs the heap to be set, for others ergonomics
-# will do the rest. It is important to use ea, which can expose class
-# format errors much earlier than later.
-
-OS=`uname -s`
-
-
-case "$OS" in
-  Windows*|CYGWIN* )
-    PackOptions="-J-Xmx512m -J-ea"
-    break
-    ;;
-
-  Linux )
-    PackOptions="-J-Xmx512m -J-ea"
-    break
-    ;;
-
-  * )
-    PackOptions="-J-ea"
-    ;;
-esac
-
-# Creates a packfile of choice expects 1 argument the filename
-createConfigFile() {
- # optimize for speed
- printf "pack.effort=1\n" > $1
- # we DO want to know about new attributes
- printf "pack.unknown.attribute=error\n" >> $1
- # optimize for speed
- printf "pack.deflate.hint=false\n" >> $1
- # keep the ordering for easy compare
- printf "pack.keep.class.order=true\n" >> $1
-}
-
-
-# Tests a given jar, expects 1 argument the fully qualified
-# name to a test jar, it writes all output to the current
-# directory which is a scratch  area.
-testAJar() {
-  PackConf="pack.conf"
-  createConfigFile $PackConf
-
-  # Try some command line options
-  CLIPackOptions="$PackOptions -v --no-gzip --segment-limit=10000 --config-file=$PackConf"
-
-  jfName=`basename $1`
-
-  ${PACK200}   $CLIPackOptions  ${jfName}.pack $1 > ${jfName}.pack.log 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName packing failed"
-  fi
-
-  # We want to test unpack200, therefore we dont use -r with pack
-  ${UNPACK200} -v ${jfName}.pack $jfName > ${jfName}.unpack.log 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName unpacking failed"
-  fi
-
-  # A quick crc compare test to ensure a well formed zip
-  # archive, this is a critical unpack200 behaviour.
-
-  unzip -t $jfName > ${jfName}.unzip.log 2>&1 
-  if [ $? != 0 ]; then
-    errorOut "$jfName unzip -t test failed"
-  fi
-
-  # The PACK200 signature should be at the top of the log
-  # this tag is critical for deployment related tools.
-
-  head -5 ${jfName}.unzip.log | grep PACK200 > /dev/null 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName PACK200 signature missing"
-  fi
-
-
-  # we know  the size fields don't match, strip 'em out, its
-  # extremely important to ensure that the date stamps match up.
-  # Don't EVER sort the output we are checking for correct ordering.
-
-  ${JAR} -tvf $1 | sed -e 's/^ *[0-9]* //g'> ${jfName}.ref.txt
-  ${JAR} -tvf $jfName | sed -e 's/^ *[0-9]* //g'> ${jfName}.cmp.txt
-
-  diff ${jfName}.ref.txt ${jfName}.cmp.txt > ${jfName}.diff.log 2>&1
-  if [ $? != 0 ]; then
-    errorOut "$jfName files missing"
-  fi
-}
-
-# These JARs are the largest and also the most likely specimens to 
-# expose class format issues and stress the packer as well.
-
-JLIST="${TESTJAVA}/lib/tools.jar ${TESTJAVA}/jre/lib/rt.jar"
-
-
-# Test the Command Line Interfaces (CLI).
-mkdir cliTestDir 
-_pwd=`pwd`
-cd cliTestDir
-
-for jarfile in $JLIST ; do 
-  if [ -f $jarfile ]; then
-    testAJar $jarfile
-  else
-    errorOut "Error: '$jarFile' does not exist\nTest requires a j2sdk-image\n"
-  fi
-done
-cd $_pwd
-
-# Test the Java APIs.
-mkdir apiTestDir 
-_pwd=`pwd`
-cd  apiTestDir
-
-# Strip out the -J prefixes.
-JavaPackOptions=`printf %s "$PackOptions" | sed -e 's/-J//g'`
-
-# Test the Java APIs now.
-$TESTJAVA/bin/java $JavaPackOptions -cp $TESTCLASSES Pack200Test $JLIST || exit 1
-
-cd $_pwd
-
-exit 0
--- a/jdk/test/tools/pack200/Pack200Test.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/tools/pack200/Pack200Test.java	Thu Sep 02 12:17:21 2010 -0700
@@ -24,111 +24,97 @@
 
 import java.util.*;
 import java.io.*;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
 import java.util.jar.*;
-import java.util.zip.*;
 
-/*
- * Pack200Test.java
- *
- * @author ksrini
- */
+ /*
+  * @test
+  * @bug 6521334 6712743
+  * @summary check for memory leaks, test general packer/unpacker functionality\
+  *          using native and java unpackers
+  * @compile -XDignore.symbol.file Utils.java Pack200Test.java
+  * @run main/othervm/timeout=1200 -Xmx512m Pack200Test
+  * @author ksrini
+  */
 
 /**
- * These tests are very rudimentary smoke tests to ensure that the packing
- * unpacking process works on a select set of JARs.
+ * Tests the packing/unpacking via the APIs.
  */
 public class Pack200Test {
 
     private static ArrayList <File> jarList = new ArrayList<File>();
-    static final String PACKEXT = ".pack";
+    static final MemoryMXBean mmxbean = ManagementFactory.getMemoryMXBean();
+    static final long m0 = getUsedMemory();
+    static final int LEAK_TOLERANCE = 20000; // OS and GC related variations.
 
     /** Creates a new instance of Pack200Test */
     private Pack200Test() {}
 
-    private static void doPackUnpack() {
-        for (File in : jarList) {
-            Pack200.Packer packer = Pack200.newPacker();
-            Map<String, String> p = packer.properties();
-            // Take the time optimization vs. space
-            p.put(packer.EFFORT, "1");  // CAUTION: do not use 0.
-            // Make the memory consumption as effective as possible
-            p.put(packer.SEGMENT_LIMIT,"10000");
-            // throw an error if an attribute is unrecognized
-            p.put(packer.UNKNOWN_ATTRIBUTE, packer.ERROR);
-            // ignore all JAR deflation requests to save time
-            p.put(packer.DEFLATE_HINT, packer.FALSE);
-            // save the file ordering of the original JAR
-            p.put(packer.KEEP_FILE_ORDER, packer.TRUE);
-
-            try {
-                JarFile jarFile = new JarFile(in);
-
-                // Write out to a jtreg scratch area
-                FileOutputStream fos = new FileOutputStream(in.getName() + PACKEXT);
+    static long getUsedMemory() {
+        mmxbean.gc();
+        mmxbean.gc();
+        mmxbean.gc();
+        return mmxbean.getHeapMemoryUsage().getUsed()/1024;
+    }
 
-                System.out.print("Packing [" + in.toString() + "]...");
-                // Call the packer
-                packer.pack(jarFile, fos);
-                jarFile.close();
-                fos.close();
-
-                System.out.print("Unpacking...");
-                File f = new File(in.getName() + PACKEXT);
-
-                // Write out to current directory, jtreg will setup a scratch area
-                JarOutputStream jostream = new JarOutputStream(new FileOutputStream(in.getName()));
-
-                // Unpack the files
-                Pack200.Unpacker unpacker = Pack200.newUnpacker();
-                // Call the unpacker
-                unpacker.unpack(f, jostream);
-                // Must explicitly close the output.
-                jostream.close();
-                System.out.print("Testing...");
-                // Ok we have unpacked the file, lets test it.
-                doTest(in);
-                System.out.println("Done.");
-            } catch (Exception e) {
-                System.out.println("ERROR: " + e.getMessage());
-                System.exit(1);
-            }
+    private static void leakCheck() throws Exception {
+        long diff = getUsedMemory() - m0;
+        System.out.println("  Info: memory diff = " + diff + "K");
+        if ( diff  > LEAK_TOLERANCE) {
+            throw new Exception("memory leak detected " + diff);
         }
     }
 
-    private static ArrayList <String> getZipFileEntryNames(ZipFile z) {
-        ArrayList <String> out = new ArrayList<String>();
-        for (ZipEntry ze : Collections.list(z.entries())) {
-            out.add(ze.getName());
-        }
-        return out;
-    }
+    private static void doPackUnpack() {
+        for (File in : jarList) {
+            JarOutputStream javaUnpackerStream = null;
+            JarOutputStream nativeUnpackerStream = null;
+            JarFile jarFile = null;
+            try {
+                jarFile = new JarFile(in);
 
-    private static void doTest(File in) throws Exception {
-       // make sure all the files in the original jar exists in the other
-       ArrayList <String> refList = getZipFileEntryNames(new ZipFile(in));
-       ArrayList <String> cmpList = getZipFileEntryNames(new ZipFile(in.getName()));
+                // Write out to a jtreg scratch area
+                File packFile = new File(in.getName() + Utils.PACK_FILE_EXT);
 
-       System.out.print(refList.size() + "/" + cmpList.size() + " entries...");
+                System.out.println("Packing [" + in.toString() + "]");
+                // Call the packer
+                Utils.pack(jarFile, packFile);
+                jarFile.close();
+                leakCheck();
 
-       if (refList.size() != cmpList.size()) {
-           throw new Exception("Missing: files ?, entries don't match");
-       }
+                System.out.println("  Unpacking using java unpacker");
+                File javaUnpackedJar = new File("java-" + in.getName());
+                // Write out to current directory, jtreg will setup a scratch area
+                javaUnpackerStream = new JarOutputStream(
+                        new FileOutputStream(javaUnpackedJar));
+                Utils.unpackj(packFile, javaUnpackerStream);
+                javaUnpackerStream.close();
+                System.out.println("  Testing...java unpacker");
+                leakCheck();
+                // Ok we have unpacked the file, lets test it.
+                Utils.doCompareVerify(in.getAbsoluteFile(), javaUnpackedJar);
 
-       for (String ename: refList) {
-          if (!cmpList.contains(ename)) {
-              throw new Exception("Does not contain : " + ename);
-          }
-       }
-    }
-
-    private static void doSanity(String[] args) {
-        for (String s: args) {
-            File f = new File(s);
-            if (f.exists()) {
-                jarList.add(f);
-            } else {
-                System.out.println("Warning: The JAR file " + f.toString() + " does not exist,");
-                System.out.println("         this test requires a JDK image, this file will be skipped.");
+                System.out.println("  Unpacking using native unpacker");
+                // Write out to current directory
+                File nativeUnpackedJar = new File("native-" + in.getName());
+                nativeUnpackerStream = new JarOutputStream(
+                        new FileOutputStream(nativeUnpackedJar));
+                Utils.unpackn(packFile, nativeUnpackerStream);
+                nativeUnpackerStream.close();
+                System.out.println("  Testing...native unpacker");
+                leakCheck();
+                // the unpackers (native and java) should produce identical bits
+                // so we use use bit wise compare, the verification compare is
+                // very expensive wrt. time.
+                Utils.doCompareBitWise(javaUnpackedJar, nativeUnpackedJar);
+                System.out.println("Done.");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            } finally {
+                Utils.close(nativeUnpackerStream);
+                Utils.close(javaUnpackerStream);
+                Utils.close((Closeable) jarFile);
             }
         }
     }
@@ -137,11 +123,12 @@
      * @param args the command line arguments
      */
     public static void main(String[] args) {
-        if (args.length < 1) {
-            System.out.println("Usage: jar1 jar2 jar3 .....");
-            System.exit(1);
-        }
-        doSanity(args);
+        // select the jars carefully, adding more jars will increase the
+        // testing time, especially for jprt.
+        jarList.add(Utils.locateJar("tools.jar"));
+        jarList.add(Utils.locateJar("rt.jar"));
+        jarList.add(Utils.locateJar("golden.jar"));
+        System.out.println(jarList);
         doPackUnpack();
     }
 }
--- a/jdk/test/tools/pack200/PackageVersionTest.java	Tue Aug 31 15:05:09 2010 +0400
+++ b/jdk/test/tools/pack200/PackageVersionTest.java	Thu Sep 02 12:17:21 2010 -0700
@@ -22,13 +22,14 @@
  * questions.
  */
 
-/**
-  * @test
-  * @bug 6712743
-  * @summary verify package versioning
-  * @compile -XDignore.symbol.file PackageVersionTest.java
-  * @run main PackageVersionTest
-  */
+/*
+ * @test
+ * @bug 6712743
+ * @summary verify package versions
+ * @compile -XDignore.symbol.file Utils.java PackageVersionTest.java
+ * @run main PackageVersionTest
+ * @author ksrini
+ */
 
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
@@ -74,14 +75,6 @@
                 JAVA5_PACKAGE_MINOR_VERSION);
     }
 
-    static void close(Closeable c) {
-        if (c == null) {
-            return;
-        }
-        try {
-            c.close();
-        } catch (IOException ignore) {}
-    }
 
     static void createClassFile(String name) {
         createJavaFile(name);
@@ -93,7 +86,7 @@
             name.substring(name.length() - 1),
             name + ".java"
         };
-        compileJava(javacCmds);
+        Utils.compiler(javacCmds);
     }
 
     static void createJavaFile(String name) {
@@ -108,22 +101,8 @@
         } catch (IOException ioe) {
             throw new RuntimeException("creation of test file failed");
         } finally {
-            close(ps);
-            close(fos);
-        }
-    }
-
-    static void compileJava(String... javacCmds) {
-        if (com.sun.tools.javac.Main.compile(javacCmds) != 0) {
-            throw new RuntimeException("compilation failed");
-        }
-    }
-
-    static void makeJar(String... jargs) {
-        sun.tools.jar.Main jarTool =
-                new sun.tools.jar.Main(System.out, System.err, "jartool");
-        if (!jarTool.run(jargs)) {
-            throw new RuntimeException("jar command failed");
+            Utils.close(ps);
+            Utils.close(fos);
         }
     }
 
@@ -136,7 +115,7 @@
             jarFileName.getName(),
             filename
         };
-        makeJar(jargs);
+        Utils.jar(jargs);
         JarFile jfin = null;
 
         try {
@@ -163,7 +142,7 @@
         } catch (IOException ioe) {
             throw new RuntimeException(ioe.getMessage());
         } finally {
-            close(jfin);
+            Utils.close((Closeable) jfin);
         }
     }
 }
--- a/jdk/test/tools/pack200/SegmentLimit.java	Tue Aug 31 15:05:09 2010 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 6575373
- * @summary verify default segment limit
- * @compile SegmentLimit.java
- * @run main SegmentLimit
- */
-
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-
-/*
- * Run this against a large jar file, by default the packer should generate only
- * one segment, parse the output of the packer to verify if this is indeed true.
- */
-
-public class SegmentLimit {
-
-    private static final File  javaHome = new File(System.getProperty("java.home"));
-
-    public static void main(String... args) {
-        if (!javaHome.getName().endsWith("jre")) {
-            throw new RuntimeException("Error: requires an SDK to run");
-        }
-
-        File out = new File("test" + Pack200Test.PACKEXT);
-        out.delete();
-        runPack200(out);
-    }
-
-    static void close(Closeable c) {
-        if (c == null) {
-            return;
-        }
-        try {
-            c.close();
-        } catch (IOException ignore) {}
-    }
-
-    static void runPack200(File outFile) {
-        File binDir = new File(javaHome, "bin");
-        File pack200Exe = System.getProperty("os.name").startsWith("Windows")
-                ? new File(binDir, "pack200.exe")
-                : new File(binDir, "pack200");
-        File sdkHome = javaHome.getParentFile();
-        File testJar = new File(new File(sdkHome, "lib"), "tools.jar");
-
-        System.out.println("using pack200: " + pack200Exe.getAbsolutePath());
-
-        String[] cmds = { pack200Exe.getAbsolutePath(),
-                          "--effort=1",
-                          "--verbose",
-                          "--no-gzip",
-                          outFile.getName(),
-                          testJar.getAbsolutePath()
-        };
-        InputStream is = null;
-        BufferedReader br = null;
-        InputStreamReader ir = null;
-
-        FileOutputStream fos = null;
-        PrintStream ps = null;
-
-        try {
-            ProcessBuilder pb = new ProcessBuilder(cmds);
-            pb.redirectErrorStream(true);
-            Process p = pb.start();
-            is = p.getInputStream();
-            ir = new InputStreamReader(is);
-            br = new BufferedReader(ir);
-
-            File logFile = new File("pack200.log");
-            fos = new FileOutputStream(logFile);
-            ps  = new PrintStream(fos);
-
-            String line = br.readLine();
-            int count = 0;
-            while (line != null) {
-                line = line.trim();
-                if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) {
-                    count++;
-                }
-                ps.println(line);
-                line=br.readLine();
-            }
-            p.waitFor();
-            if (p.exitValue() != 0) {
-                throw new RuntimeException("pack200 failed");
-            }
-            p.destroy();
-            if (count > 1) {
-                throw new Error("test fails: check for multiple segments(" +
-                        count + ") in: " + logFile.getAbsolutePath());
-            }
-        } catch (IOException ex) {
-            throw new RuntimeException(ex.getMessage());
-        } catch (InterruptedException ignore){
-        } finally {
-            close(is);
-            close(ps);
-            close(fos);
-        }
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/TimeStamp.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+/*
+ * @test
+ * @bug 6966740
+ * @summary verify identical timestamps, unpacked in any timezone
+ * @compile -XDignore.symbol.file Utils.java TimeStamp.java
+ * @run main/othervm TimeStamp
+ * @author ksrini
+ */
+
+/**
+ * First we pack the file in some time zone say India, then we unpack the  file
+ * in the current time zone, and ensure the timestamp recorded in the unpacked
+ * jar are the same.
+ */
+public class TimeStamp {
+    static final TimeZone tz = TimeZone.getDefault();
+
+
+    public static void main(String... args) throws IOException {
+
+        // make a local copy of our test file
+        File srcFile = Utils.locateJar("golden.jar");
+        File goldenFile = new File("golden.jar");
+        Utils.copyFile(srcFile, goldenFile.getAbsoluteFile());
+
+        JarFile goldenJarFile = new JarFile(goldenFile);
+        File packFile = new File("golden.pack");
+
+        // set the test timezone and pack the file
+        TimeZone.setDefault(TimeZone.getTimeZone("IST"));
+        Utils.pack(goldenJarFile, packFile);
+        TimeZone.setDefault(tz);   // reset the timezone
+
+        // unpack in the  test timezone
+        File istFile = new File("golden.jar.java.IST");
+        unpackJava(packFile, istFile);
+        verifyJar(goldenFile, istFile);
+        istFile.delete();
+
+        // unpack in some other timezone
+        File pstFile = new File("golden.jar.java.PST");
+        unpackJava(packFile, pstFile);
+        verifyJar(goldenFile, pstFile);
+        pstFile.delete();
+
+        // repeat the test for unpack200 tool.
+        istFile = new File("golden.jar.native.IST");
+        unpackNative(packFile, istFile);
+        verifyJar(goldenFile, istFile);
+        istFile.delete();
+
+        pstFile = new File("golden.jar.native.PST");
+        unpackNative(packFile, pstFile);
+        verifyJar(goldenFile, pstFile);
+        pstFile.delete();
+    }
+
+    static void unpackNative(File packFile, File outFile) {
+        String name = outFile.getName();
+        String tzname = name.substring(name.lastIndexOf(".") + 1);
+        HashMap<String, String> env = new HashMap<>();
+        switch(tzname) {
+            case "PST":
+                env.put("TZ", "US/Pacific");
+                break;
+            case "IST":
+                env.put("TZ", "Asia/Calcutta");
+                break;
+            default:
+                throw new RuntimeException("not implemented: " + tzname);
+        }
+        List<String> cmdsList = new ArrayList<>();
+        cmdsList.add(Utils.getUnpack200Cmd());
+        cmdsList.add(packFile.getName());
+        cmdsList.add(outFile.getName());
+        Utils.runExec(cmdsList, env);
+    }
+
+    static void unpackJava(File packFile, File outFile) throws IOException {
+        String name = outFile.getName();
+        String tzname = name.substring(name.lastIndexOf(".") + 1);
+        JarOutputStream jos = null;
+        try {
+            TimeZone.setDefault(TimeZone.getTimeZone(tzname));
+            jos = new JarOutputStream(new FileOutputStream(outFile));
+            System.out.println("Using timezone: " + TimeZone.getDefault());
+            Utils.unpackj(packFile, jos);
+        } finally {
+            Utils.close(jos);
+            TimeZone.setDefault(tz); // always reset
+        }
+    }
+
+    static void verifyJar(File f1, File f2) throws IOException {
+        int errors = 0;
+        JarFile jf1 = null;
+        JarFile jf2 = null;
+        try {
+            jf1 = new JarFile(f1);
+            jf2 = new JarFile(f2);
+            System.out.println("Verifying: " + f1 + " and " + f2);
+            for (JarEntry je1 : Collections.list(jf1.entries())) {
+                JarEntry je2 = jf2.getJarEntry(je1.getName());
+                if (je1.getTime() != je2.getTime()) {
+                    System.out.println("Error:");
+                    System.out.println("  expected:" + jf1.getName() + ":"
+                            + je1.getName() + ":" + je1.getTime());
+                    System.out.println("  obtained:" + jf2.getName() + ":"
+                            + je2.getName() + ":" + je2.getTime());
+                    errors++;
+                }
+            }
+        } finally {
+            Utils.close(jf1);
+            Utils.close(jf2);
+        }
+        if (errors > 0) {
+            throw new RuntimeException("FAIL:" + errors + " error(s) encounted");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/UnpackerMemoryTest.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6531345
+ * @summary check for unpacker memory leaks
+ * @compile -XDignore.symbol.file Utils.java UnpackerMemoryTest.java
+ * @run main/othervm/timeout=1200 -Xmx32m UnpackerMemoryTest
+ * @author ksrini
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+public class UnpackerMemoryTest {
+
+    private static void createPackFile(File packFile) throws IOException {
+        File tFile = new File("test.dat");
+        FileOutputStream fos = null;
+        PrintStream ps = null;
+        String jarFileName = Utils.baseName(packFile, Utils.PACK_FILE_EXT)
+                + Utils.JAR_FILE_EXT;
+        JarFile jarFile = null;
+        try {
+            fos = new FileOutputStream(tFile);
+            ps = new PrintStream(fos);
+            ps.println("A quick brown fox");
+            Utils.jar("cvf", jarFileName, tFile.getName());
+            jarFile = new JarFile(jarFileName);
+            Utils.pack(jarFile, packFile);
+        } finally {
+            Utils.close(ps);
+            tFile.delete();
+            Utils.close(jarFile);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        String name = "foo";
+        File packFile = new File(name + Utils.PACK_FILE_EXT);
+        createPackFile(packFile);
+        if (!packFile.exists()) {
+           throw new RuntimeException(packFile + " not found");
+        }
+        File jarOut = new File(name + ".out");
+        for (int i = 0; i < 2000; i++) {
+            JarOutputStream jarOS = null;
+            FileOutputStream fos = null;
+            try {
+                fos = new FileOutputStream(jarOut);
+                jarOS = new JarOutputStream(fos);
+                System.out.println("Unpacking[" + i + "]" + packFile);
+                Utils.unpackn(packFile, jarOS);
+            }  finally {
+                Utils.close(jarOS);
+                Utils.close(fos);
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/Utils.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,516 @@
+/*
+ * 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
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Pack200;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ *
+ * @author ksrini
+ */
+
+/*
+ * This class contains all the commonly used utilities used by various tests
+ * in this directory.
+ */
+class Utils {
+    static final String JavaHome = System.getProperty("test.java",
+            System.getProperty("java.home"));
+    static final boolean IsWindows =
+            System.getProperty("os.name").startsWith("Windows");
+    static final boolean Is64Bit =
+            System.getProperty("sun.arch.data.model", "32").equals("64");
+    static final File   JavaSDK =  new File(JavaHome).getParentFile();
+
+    static final String PACK_FILE_EXT   = ".pack";
+    static final String JAVA_FILE_EXT   = ".java";
+    static final String CLASS_FILE_EXT  = ".class";
+    static final String JAR_FILE_EXT    = ".jar";
+
+    static final File   TEST_SRC_DIR = new File(System.getProperty("test.src"));
+    static final String VERIFIER_DIR_NAME = "pack200-verifier";
+    static final File   VerifierJar = new File(VERIFIER_DIR_NAME + JAR_FILE_EXT);
+
+    private Utils() {} // all static
+
+    static {
+        if (!JavaHome.endsWith("jre")) {
+            throw new RuntimeException("Error: requires an SDK to run");
+        }
+    }
+
+    private static void init() throws IOException {
+        if (VerifierJar.exists()) {
+            return;
+        }
+        File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME);
+        List<File> javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT));
+        File tmpFile = File.createTempFile("javac", ".tmp");
+        File classesDir = new File("xclasses");
+        classesDir.mkdirs();
+        FileOutputStream fos = null;
+        PrintStream ps = null;
+        try {
+            fos = new FileOutputStream(tmpFile);
+            ps = new PrintStream(fos);
+            for (File f : javaFileList) {
+                ps.println(f.getAbsolutePath());
+            }
+        } finally {
+            close(ps);
+            close(fos);
+        }
+
+        compiler("-d",
+                "xclasses",
+                "@" + tmpFile.getAbsolutePath());
+
+        jar("cvfe",
+            VerifierJar.getName(),
+            "sun.tools.pack.verify.Main",
+            "-C",
+            "xclasses",
+            ".");
+    }
+
+    static void dirlist(File dir) {
+        File[] files = dir.listFiles();
+        System.out.println("--listing " + dir.getAbsolutePath() + "---");
+        for (File f : files) {
+            StringBuffer sb = new StringBuffer();
+            sb.append(f.isDirectory() ? "d " : "- ");
+            sb.append(f.getName());
+            System.out.println(sb);
+        }
+    }
+    static void doCompareVerify(File reference, File specimen) throws IOException {
+        init();
+        List<String> cmds = new ArrayList<String>();
+        cmds.add(getJavaCmd());
+        cmds.add("-jar");
+        cmds.add(VerifierJar.getName());
+        cmds.add(reference.getAbsolutePath());
+        cmds.add(specimen.getAbsolutePath());
+        cmds.add("-O");
+        runExec(cmds);
+    }
+
+    static void doCompareBitWise(File reference, File specimen)
+            throws IOException {
+        init();
+        List<String> cmds = new ArrayList<String>();
+        cmds.add(getJavaCmd());
+        cmds.add("-jar");
+        cmds.add(VerifierJar.getName());
+        cmds.add(reference.getName());
+        cmds.add(specimen.getName());
+        cmds.add("-O");
+        cmds.add("-b");
+        runExec(cmds);
+    }
+
+    static FileFilter createFilter(final String extension) {
+        return new FileFilter() {
+            @Override
+            public boolean accept(File pathname) {
+                String name = pathname.getName();
+                if (name.endsWith(extension)) {
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+
+    static final FileFilter DIR_FILTER = new FileFilter() {
+        public boolean accept(File pathname) {
+            if (pathname.isDirectory()) {
+                return true;
+            }
+            return false;
+        }
+    };
+
+    static final FileFilter FILE_FILTER = new FileFilter() {
+        public boolean accept(File pathname) {
+            if (pathname.isFile()) {
+                return true;
+            }
+            return false;
+        }
+    };
+
+    private static void setFileAttributes(File src, File dst) throws IOException {
+        dst.setExecutable(src.canExecute());
+        dst.setReadable(src.canRead());
+        dst.setWritable(src.canWrite());
+        dst.setLastModified(src.lastModified());
+    }
+
+    static void copyFile(File src, File dst) throws IOException {
+        if (src.isDirectory()) {
+            dst.mkdirs();
+            setFileAttributes(src, dst);
+            return;
+        } else {
+            File baseDirFile = dst.getParentFile();
+            if (!baseDirFile.exists()) {
+                baseDirFile.mkdirs();
+            }
+        }
+        FileInputStream in = null;
+        FileOutputStream out = null;
+        FileChannel srcChannel = null;
+        FileChannel dstChannel = null;
+        try {
+            in = new FileInputStream(src);
+            out = new FileOutputStream(dst);
+            srcChannel = in.getChannel();
+            dstChannel = out.getChannel();
+
+            long retval = srcChannel.transferTo(0, src.length(), dstChannel);
+            if (src.length() != dst.length()) {
+                throw new IOException("file copy failed for " + src);
+            }
+        } finally {
+            close(srcChannel);
+            close(dstChannel);
+            close(in);
+            close(out);
+        }
+        setFileAttributes(src, dst);
+    }
+
+    static String baseName(File file, String extension) {
+        return baseName(file.getAbsolutePath(), extension);
+    }
+
+    static String baseName(String name, String extension) {
+        int cut = name.length() - extension.length();
+        return name.lastIndexOf(extension) == cut
+                ? name.substring(0, cut)
+                : name;
+
+    }
+
+    /*
+     * Suppose a path is provided which consists of a full path
+     * this method returns the sub path for a full path ex: /foo/bar/baz/foobar.z
+     * and the base path is /foo/bar it will will return baz/foobar.z.
+     */
+    private static String getEntryPath(String basePath, String fullPath) {
+        if (!fullPath.startsWith(basePath)) {
+            return null;
+        }
+        return fullPath.substring(basePath.length());
+    }
+
+    static String getEntryPath(File basePathFile, File fullPathFile) {
+        return getEntryPath(basePathFile.toString(), fullPathFile.toString());
+    }
+
+    public static void recursiveCopy(File src, File dest) throws IOException {
+        if (!src.exists() || !src.canRead()) {
+            throw new IOException("file not found or readable: " + src);
+        }
+        if (dest.exists() && !dest.isDirectory() && !dest.canWrite()) {
+            throw new IOException("file not found or writeable: " + dest);
+        }
+        if (!dest.exists()) {
+            dest.mkdirs();
+        }
+        List<File> a = directoryList(src);
+        for (File f : a) {
+            copyFile(f, new File(dest, getEntryPath(src, f)));
+        }
+    }
+
+    static List<File> directoryList(File dirname) {
+        List<File>  dirList = new ArrayList<File>();
+        return directoryList(dirname, dirList, null);
+    }
+
+    private static List<File> directoryList(File dirname, List<File> dirList,
+            File[] dirs) {
+        dirList.addAll(Arrays.asList(dirname.listFiles(FILE_FILTER)));
+        dirs = dirname.listFiles(DIR_FILTER);
+        for (File f : dirs) {
+            if (f.isDirectory() && !f.equals(dirname)) {
+                dirList.add(f);
+                directoryList(f, dirList, dirs);
+            }
+        }
+        return dirList;
+    }
+
+    static void recursiveDelete(File dir) throws IOException {
+        if (dir.isFile()) {
+            dir.delete();
+        } else if (dir.isDirectory()) {
+            File[] entries = dir.listFiles();
+            for (int i = 0; i < entries.length; i++) {
+                if (entries[i].isDirectory()) {
+                    recursiveDelete(entries[i]);
+                }
+                entries[i].delete();
+            }
+            dir.delete();
+        }
+    }
+
+    static List<File> findFiles(File startDir, FileFilter filter)
+            throws IOException {
+        List<File> list = new ArrayList<File>();
+        findFiles0(startDir, list, filter);
+        return list;
+    }
+    /*
+     * finds files in the start directory using the the filter, appends
+     * the files to the dirList.
+     */
+    private static void findFiles0(File startDir, List<File> list,
+                                    FileFilter filter) throws IOException {
+        File[] foundFiles = startDir.listFiles(filter);
+        list.addAll(Arrays.asList(foundFiles));
+        File[] dirs = startDir.listFiles(DIR_FILTER);
+        for (File dir : dirs) {
+            findFiles0(dir, list, filter);
+        }
+    }
+
+    static void close(Closeable c) {
+        if (c == null) {
+            return;
+        }
+        try {
+            c.close();
+        } catch (IOException ignore) {
+        }
+    }
+
+    static void compiler(String... javacCmds) {
+        if (com.sun.tools.javac.Main.compile(javacCmds) != 0) {
+            throw new RuntimeException("compilation failed");
+        }
+    }
+
+    static void jar(String... jargs) {
+        sun.tools.jar.Main jarTool =
+                new sun.tools.jar.Main(System.out, System.err, "jartool");
+        if (!jarTool.run(jargs)) {
+            throw new RuntimeException("jar command failed");
+        }
+    }
+
+    // given a jar file foo.jar will write to foo.pack
+    static void pack(JarFile jarFile, File packFile) throws IOException {
+        Pack200.Packer packer = Pack200.newPacker();
+        Map<String, String> p = packer.properties();
+        // Take the time optimization vs. space
+        p.put(packer.EFFORT, "1");  // CAUTION: do not use 0.
+        // Make the memory consumption as effective as possible
+        p.put(packer.SEGMENT_LIMIT, "10000");
+        // ignore all JAR deflation requests to save time
+        p.put(packer.DEFLATE_HINT, packer.FALSE);
+        // save the file ordering of the original JAR
+        p.put(packer.KEEP_FILE_ORDER, packer.TRUE);
+        FileOutputStream fos = null;
+        try {
+            // Write out to a jtreg scratch area
+            fos = new FileOutputStream(packFile);
+            // Call the packer
+            packer.pack(jarFile, fos);
+        } finally {
+            close(fos);
+        }
+    }
+
+    // uses java unpacker, slow but useful to discover issues with the packer
+    static void unpackj(File inFile, JarOutputStream jarStream)
+            throws IOException {
+        unpack0(inFile, jarStream, true);
+
+    }
+
+    // uses native unpacker using the java APIs
+    static void unpackn(File inFile, JarOutputStream jarStream)
+            throws IOException {
+        unpack0(inFile, jarStream, false);
+    }
+
+    // given a packed file, create the jar file in the current directory.
+    private static void unpack0(File inFile, JarOutputStream jarStream,
+            boolean useJavaUnpack) throws IOException {
+        // Unpack the files
+        Pack200.Unpacker unpacker = Pack200.newUnpacker();
+        Map<String, String> props = unpacker.properties();
+        if (useJavaUnpack) {
+            props.put("com.sun.java.util.jar.pack.disable.native", "true");
+        }
+        // Call the unpacker
+        unpacker.unpack(inFile, jarStream);
+    }
+
+    static byte[] getBuffer(ZipFile zf, ZipEntry ze) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte buf[] = new byte[8192];
+        InputStream is = null;
+        try {
+            is = zf.getInputStream(ze);
+            int n = is.read(buf);
+            while (n > 0) {
+                baos.write(buf, 0, n);
+                n = is.read(buf);
+            }
+            return baos.toByteArray();
+        } finally {
+            close(is);
+        }
+    }
+
+    static ArrayList<String> getZipFileEntryNames(ZipFile z) {
+        ArrayList<String> out = new ArrayList<String>();
+        for (ZipEntry ze : Collections.list(z.entries())) {
+            out.add(ze.getName());
+        }
+        return out;
+    }
+    static List<String> runExec(List<String> cmdsList) {
+        return runExec(cmdsList, null);
+    }
+    static List<String> runExec(List<String> cmdsList, Map<String, String> penv) {
+        ArrayList<String> alist = new ArrayList<String>();
+        ProcessBuilder pb =
+                new ProcessBuilder(cmdsList);
+        Map<String, String> env = pb.environment();
+        if (penv != null && !penv.isEmpty()) {
+            env.putAll(penv);
+        }
+        pb.directory(new File("."));
+        dirlist(new File("."));
+        for (String x : cmdsList) {
+            System.out.print(x + " ");
+        }
+        System.out.println("");
+        int retval = 0;
+        Process p = null;
+        InputStreamReader ir = null;
+        BufferedReader rd = null;
+        InputStream is = null;
+        try {
+            pb.redirectErrorStream(true);
+            p = pb.start();
+            is = p.getInputStream();
+            ir = new InputStreamReader(is);
+            rd = new BufferedReader(ir, 8192);
+
+            String in = rd.readLine();
+            while (in != null) {
+                alist.add(in);
+                System.out.println(in);
+                in = rd.readLine();
+            }
+            retval = p.waitFor();
+            if (retval != 0) {
+                throw new RuntimeException("process failed with non-zero exit");
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException(ex.getMessage());
+        } finally {
+            close(rd);
+            close(ir);
+            close(is);
+            if (p != null) {
+                p.destroy();
+            }
+        }
+        return alist;
+    }
+
+    static String getUnpack200Cmd() {
+        return getAjavaCmd("unpack200");
+    }
+
+    static String getPack200Cmd() {
+        return getAjavaCmd("pack200");
+    }
+
+    static String getJavaCmd() {
+        return getAjavaCmd("java");
+    }
+
+    static String getAjavaCmd(String cmdStr) {
+        File binDir = new File(JavaHome, "bin");
+        File unpack200File = IsWindows
+                ? new File(binDir, cmdStr + ".exe")
+                : new File(binDir, cmdStr);
+
+        String cmd = unpack200File.getAbsolutePath();
+        if (!unpack200File.canExecute()) {
+            throw new RuntimeException("please check" +
+                    cmd + " exists and is executable");
+        }
+        return cmd;
+    }
+
+    private static List<File> locaterCache = null;
+    // search the source dir and jdk dir for requested file and returns
+    // the first location it finds.
+    static File locateJar(String name) {
+        try {
+            if (locaterCache == null) {
+                locaterCache = new ArrayList<File>();
+                locaterCache.addAll(findFiles(TEST_SRC_DIR, createFilter(JAR_FILE_EXT)));
+                locaterCache.addAll(findFiles(JavaSDK, createFilter(JAR_FILE_EXT)));
+            }
+            for (File f : locaterCache) {
+                if (f.getName().equals(name)) {
+                    return f;
+                }
+            }
+            throw new IOException("file not found: " + name);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/data/README	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,45 @@
+The files contained in the golden.jar have been harvested from many
+different sources, some are hand-crafted invalid class files (odds directory),
+or from random JDK builds.
+
+Generally these files serve to ensure the integrity of the packer and unpacker
+by,
+   1. maximizing the test coverage.
+   2. exercising all the Bands in the pack200 specification.
+   2. testing the behavior of the packer with invalid classes.
+   3. testing the archive integrity, ordering and description (date, sizes,
+      CRC etc.)
+
+Build:
+To rebuild this JAR follow these steps:
+    1. unzip the golden.jar to some directory lets call it "example"
+    2. now we can add any directories with files into example.
+    2. run the script BUILDME.sh  as
+       % sh BUILDME.sh example
+
+Note: the BUILDME.sh is known to work on all Unix platforms as well as Windows
+      using Cygwin.
+
+The above will create two JAR files in the current directory,
+example.jar and example-cls.jar, now the example.jar can be used as the
+golden.jar.
+
+To ensure the JAR has been built correctly use jar -tvf and compare the
+results of the old jar and the newly built one, note that the compressed sizes
+may differ, however the timestamps etc. should be consistent.
+
+Test:
+    Basic:
+        % pack200 --repack test.jar golden.jar
+
+    Advanced:
+       Create a pack.conf as follows:
+       % cat pack.conf
+       com.sun.java.util.jar.pack.dump.bands=true
+
+       % pack200 --no-gzip --config-file=pack.conf \
+           --verbose golden.jar.pack golden.jar
+
+       This command will dump the Bands in a unique directory BD_XXXXXX,
+       one can inspect the directory to ensure all of the bands are being
+       generated. Familiarity of the  Pack200 specification is suggested.
\ No newline at end of file
Binary file jdk/test/tools/pack200/pack200-verifier/data/golden.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/make/build.xml	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,59 @@
+<project name="PackageVerify" default="dist" basedir="..">
+  <!-- Requires ant 1.6.1+ and JDK 1.6+-->
+
+  <!-- set global properties for this build -->
+  <property name="src"      value="${basedir}/src"/>
+  <property name="build"    value="${basedir}/build"/>
+  <property name="dist"     value="${basedir}/dist"/>
+  <property name="make"     value="${basedir}/make"/>
+  <property name="classes"  value="${build}/classes"/>
+  <property name="api"      value="${build}/api"/>
+
+  <target name="init">
+    <!-- Create the time stamp -->
+    <tstamp/>
+    <!-- Create the build directory structure used by compile -->
+    <mkdir dir="${build}"/>
+    <mkdir dir="${dist}"/>
+    <mkdir dir="${classes}"/>
+    <mkdir dir="${api}"/>
+  </target>
+
+  <target name="compile" depends="init">
+    <!-- Compile the java code from ${src} into ${build} -->
+    <javac 
+	source="1.6"
+	srcdir="${src}"
+	destdir="${build}/classes"
+	verbose="no"
+	debug="on"
+    />
+  </target>
+
+  <target name="doc" depends="init, compile">
+      <javadoc
+        source="1.6"
+        sourcepath="${src}"
+        destdir="${api}"
+      />
+  </target>
+  <target name="dist" depends="compile, doc">
+    <!-- Put everything in jar file -->
+    <jar destfile="${dist}/pack200-verifier.jar">
+	<manifest>
+	   <attribute name="Main-Class" value="sun.tools.pack.verify.Main"/>
+	</manifest>
+	<fileset dir="${classes}"/>
+    </jar>
+    <zip destfile="dist/pack200-verifier-doc.zip">
+        <fileset dir="${api}"/>
+    </zip>
+  </target>
+
+  <target name="clean">
+    <!-- Delete the ${build} and ${dist} directory trees -->
+    <delete dir="${build}"/>
+    <delete dir="${dist}"/>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/sun/tools/pack/verify/ClassCompare.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+package sun.tools.pack.verify;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import xmlkit.*;
+
+public class ClassCompare {
+
+    /*
+     * @author ksrini
+     */
+    private static XMLKit.Element getXMLelement(InputStream is,
+            boolean ignoreUnkAttrs,
+            List<String> ignoreElements) throws IOException {
+
+        ClassReader cr = new ClassReader();
+        cr.keepOrder = false;
+        XMLKit.Element e = cr.readFrom(is);
+
+        if (ignoreElements != null) {
+            XMLKit.Filter filter = XMLKit.elementFilter(ignoreElements);
+            e.removeAllInTree(filter);
+        }
+
+        if (ignoreUnkAttrs == true) {
+            // This removes any unknown attributes
+            e.removeAllInTree(XMLKit.elementFilter("Attribute"));
+        }
+        return e;
+    }
+
+    private static String getXMLPrettyString(XMLKit.Element e) throws IOException {
+        StringWriter out = new StringWriter();
+        e.writePrettyTo(out);
+        return out.toString();
+    }
+
+    private static boolean compareClass0(JarFile jf1, JarFile jf2,
+            JarEntry je, boolean ignoreUnkAttrs,
+            List<String> ignoreElements)
+            throws IOException {
+
+        InputStream is1 = jf1.getInputStream(je);
+        InputStream is2 = jf2.getInputStream(je);
+
+        // First we try to compare the bits if they are the same
+        boolean bCompare = JarFileCompare.compareStreams(is1, is2);
+
+        // If they are the same there is nothing more to do.
+        if (bCompare) {
+            Globals.println("+++" + je.getName() + "+++\t"
+                    + "b/b:PASS");
+            return bCompare;
+        }
+        is1.close();
+        is2.close();
+
+        is1 = jf1.getInputStream(je);
+        is2 = jf2.getInputStream(je);
+
+
+        XMLKit.Element e1 = getXMLelement(is1, ignoreUnkAttrs, ignoreElements);
+        XMLKit.Element e2 = getXMLelement(is2, ignoreUnkAttrs, ignoreElements);
+
+        Globals.print("+++" + je.getName() + "+++\t"
+                + e1.size() + "/" + e1.size() + ":");
+
+        boolean result = true;
+
+        if (e1.equals(e2)) {
+            Globals.println("PASS");
+        } else {
+            Globals.println("FAIL");
+            Globals.log("Strings differs");
+            Globals.log(getXMLPrettyString(e1));
+            Globals.log("----------");
+            Globals.log(getXMLPrettyString(e2));
+            result = false;
+        }
+        return result;
+    }
+
+    /*
+     * Given two Class Paths could be jars the first being a reference
+     * will execute a series of comparisons on the classname  specified
+     * The className could be null in which case it will iterate through
+     * all the classes, otherwise it will compare one class and exit.
+     */
+    public static boolean compareClass(String jar1, String jar2,
+            String className, boolean ignoreUnkAttrs,
+            List<String> ignoreElements)
+            throws IOException {
+
+        Globals.println("Unknown attributes ignored:" + ignoreUnkAttrs);
+        if (ignoreElements != null) {
+            Globals.println(ignoreElements.toString());
+        }
+
+        JarFile jf1 = new JarFile(jar1);
+        JarFile jf2 = new JarFile(jar2);
+
+        boolean result = true;
+
+        if (className == null) {
+            for (JarEntry je1 : Collections.list((Enumeration<JarEntry>) jf1.entries())) {
+                if (je1.getName().endsWith(".class")) {
+                    JarEntry je2 = jf2.getJarEntry(je1.getName());
+                    boolean pf = compareClass0(jf1, jf2, je1, ignoreUnkAttrs, ignoreElements);
+                    if (result == true) {
+                        result = pf;
+                    }
+                }
+            }
+        } else {
+            JarEntry je1 = jf1.getJarEntry(className);
+            result = compareClass0(jf1, jf2, je1, ignoreUnkAttrs, ignoreElements);
+        }
+        if (result == false) {
+            throw new RuntimeException("Class structural comparison failure");
+        }
+        return result;
+    }
+
+    public static boolean compareClass(String jar1, String jar2,
+            String className) throws IOException {
+
+        Stack<String> s = new Stack();
+        if (Globals.ignoreDebugAttributes()) {
+            s = new Stack();
+            s.push("LocalVariable");
+            s.push("LocalVariableType");
+            s.push("LineNumber");
+            s.push("SourceFile");
+        }
+        return compareClass(jar1, jar2, className, Globals.ignoreUnknownAttributes(), s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/sun/tools/pack/verify/Globals.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/*
+ * A collection of useful global utilities commonly used.
+ */
+package sun.tools.pack.verify;
+
+import java.io.*;
+import java.util.*;
+
+/*
+ * @author ksrini
+ */
+
+class Globals {
+
+    private static int errors = 0;
+    private static PrintWriter _pw = null;
+    private static String _logFileName = null;
+    private static final String DEFAULT_LOG_FILE = "verifier.log";
+    private static boolean _verbose = true;
+    private static boolean _ignoreJarDirectories = false;
+    private static boolean _checkJarClassOrdering = true;
+    private static boolean _bitWiseClassCompare = false;
+    // Ignore Deprecated, SourceFile and Synthetic
+    private static boolean _ignoreCompileAttributes = false;
+    // Ignore Debug Attributes LocalVariableTable, LocalVariableType,LineNumberTable
+    private static boolean _ignoreDebugAttributes = false;
+    private static boolean _ignoreUnknownAttributes = false;
+    private static boolean _validateClass = true;
+    private static Globals _instance = null;
+
+    static Globals getInstance() {
+        if (_instance == null) {
+            _instance = new Globals();
+            _verbose = (System.getProperty("sun.tools.pack.verify.verbose") == null)
+                    ? false : true;
+            _ignoreJarDirectories = (System.getProperty("ignoreJarDirectories") == null)
+                    ? false : true;
+        }
+        return _instance;
+    }
+
+    static boolean ignoreCompileAttributes() {
+        return _ignoreCompileAttributes;
+    }
+
+    static boolean ignoreDebugAttributes() {
+        return _ignoreDebugAttributes;
+    }
+
+    static boolean ignoreUnknownAttributes() {
+        return _ignoreUnknownAttributes;
+    }
+
+    static boolean ignoreJarDirectories() {
+        return _ignoreJarDirectories;
+    }
+
+    static boolean validateClass() {
+        return _validateClass;
+    }
+
+    static void setCheckJarClassOrdering(boolean flag) {
+        _checkJarClassOrdering = flag;
+    }
+
+    static boolean checkJarClassOrdering() {
+        return _checkJarClassOrdering;
+    }
+
+    static boolean bitWiseClassCompare() {
+        return _bitWiseClassCompare;
+    }
+
+    static boolean setBitWiseClassCompare(boolean flag) {
+        return _bitWiseClassCompare = flag;
+    }
+
+    public static boolean setIgnoreCompileAttributes(boolean flag) {
+        return _ignoreCompileAttributes = flag;
+    }
+
+    static boolean setIgnoreDebugAttributes(boolean flag) {
+        return _ignoreDebugAttributes = flag;
+    }
+
+    static boolean setIgnoreUnknownAttributes(boolean flag) {
+        return _ignoreUnknownAttributes = flag;
+    }
+
+    static boolean setValidateClass(boolean flag) {
+        return _validateClass = flag;
+    }
+
+    static int getErrors() {
+        return errors;
+    }
+
+    static void trace(String s) {
+        if (_verbose) {
+            println(s);
+        }
+    }
+
+    static void print(String s) {
+        _pw.print(s);
+    }
+
+    static void println(String s) {
+        _pw.println(s);
+    }
+
+    static void log(String s) {
+        errors++;
+        _pw.println("ERROR:" + s);
+    }
+
+    static void lognoln(String s) {
+        errors++;
+        _pw.print(s);
+    }
+
+    private static PrintWriter openFile(String fileName) {
+        //Lets create the directory if it does not exist.
+        File f = new File(fileName);
+        File baseDir = f.getParentFile();
+        if (baseDir != null && baseDir.exists() == false) {
+            baseDir.mkdirs();
+        }
+        try {
+            return new PrintWriter(new FileWriter(f), true);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void closeFile() {
+        _pw.flush();
+        _pw.close();
+    }
+
+    static void printPropsToLog() {
+        println("Log started " + new Date(System.currentTimeMillis()));
+        print(System.getProperty("java.vm.version"));
+        println("\t" + System.getProperty("java.vm.name"));
+
+        println("System properties");
+        println("\tjava.home=" + System.getProperty("java.home"));
+        println("\tjava.class.version=" + System.getProperty("java.class.version"));
+        println("\tjava.class.path=" + System.getProperty("java.class.path"));
+        println("\tjava.ext.dirs=" + System.getProperty("java.ext.dirs"));
+        println("\tos.name=" + System.getProperty("os.name"));
+        println("\tos.arch=" + System.getProperty("os.arch"));
+        println("\tos.version=" + System.getProperty("os.version"));
+        println("\tuser.name=" + System.getProperty("user.name"));
+        println("\tuser.home=" + System.getProperty("user.home"));
+        println("\tuser.dir=" + System.getProperty("user.dir"));
+        println("\tLocale.getDefault=" + Locale.getDefault());
+        println("System properties end");
+    }
+
+    static void openLog(String s) {
+        _logFileName = (s != null) ? s : "." + File.separator + DEFAULT_LOG_FILE;
+        _logFileName = (new File(_logFileName).isDirectory())
+                ? _logFileName + File.separator + DEFAULT_LOG_FILE : _logFileName;
+        _pw = openFile(_logFileName);
+        printPropsToLog();
+    }
+
+    static void closeLog() {
+        closeFile();
+    }
+
+    static String getLogFileName() {
+        return _logFileName;
+    }
+
+    static void diffCharData(String s1, String s2) {
+        boolean diff = false;
+        char[] c1 = s1.toCharArray();
+        char[] c2 = s2.toCharArray();
+        if (c1.length != c2.length) {
+            diff = true;
+            Globals.log("Length differs: " + (c1.length - c2.length));
+        }
+        // Take the smaller of the two arrays to prevent Array...Exception
+        int minlen = (c1.length < c2.length) ? c1.length : c2.length;
+        for (int i = 0; i < c1.length; i++) {
+            if (c1[i] != c2[i]) {
+                diff = true;
+                Globals.lognoln("\t idx[" + i + "] 0x" + Integer.toHexString(c1[i]) + "<>" + "0x" + Integer.toHexString(c2[i]));
+                Globals.log(" -> " + c1[i] + "<>" + c2[i]);
+            }
+        }
+    }
+
+    static void diffByteData(String s1, String s2) {
+        boolean diff = false;
+        byte[] b1 = s1.getBytes();
+        byte[] b2 = s2.getBytes();
+
+        if (b1.length != b2.length) {
+            diff = true;
+            //(+) b1 is greater, (-) b2 is greater
+            Globals.log("Length differs diff: " + (b1.length - b2.length));
+        }
+        // Take the smaller of the two array to prevent Array...Exception
+        int minlen = (b1.length < b2.length) ? b1.length : b2.length;
+        for (int i = 0; i < b1.length; i++) {
+            if (b1[i] != b2[i]) {
+                diff = true;
+                Globals.log("\t" + "idx[" + i + "] 0x" + Integer.toHexString(b1[i]) + "<>" + "0x" + Integer.toHexString(b2[i]));
+            }
+        }
+    }
+
+    static void dumpToHex(String s) {
+        try {
+            dumpToHex(s.getBytes("UTF-8"));
+        } catch (UnsupportedEncodingException uce) {
+            throw new RuntimeException(uce);
+        }
+    }
+
+    static void dumpToHex(byte[] buffer) {
+        int linecount = 0;
+        byte[] b = new byte[16];
+        for (int i = 0; i < buffer.length; i += 16) {
+            if (buffer.length - i > 16) {
+                System.arraycopy(buffer, i, b, 0, 16);
+                print16Bytes(b, linecount);
+                linecount += 16;
+            } else {
+                System.arraycopy(buffer, i, b, 0, buffer.length - i);
+                for (int n = buffer.length - (i + 1); n < 16; n++) {
+                    b[n] = 0;
+                }
+                print16Bytes(b, linecount);
+                linecount += 16;
+            }
+        }
+        Globals.log("-----------------------------------------------------------------");
+    }
+
+    static void print16Bytes(byte[] buffer, int linecount) {
+        final int MAX = 4;
+        Globals.lognoln(paddedHexString(linecount, 4) + " ");
+
+        for (int i = 0; i < buffer.length; i += 2) {
+            int iOut = pack2Bytes2Int(buffer[i], buffer[i + 1]);
+            Globals.lognoln(paddedHexString(iOut, 4) + " ");
+        }
+
+        Globals.lognoln("| ");
+
+        StringBuilder sb = new StringBuilder(new String(buffer));
+
+        for (int i = 0; i < buffer.length; i++) {
+            if (Character.isISOControl(sb.charAt(i))) {
+                sb.setCharAt(i, '.');
+            }
+        }
+        Globals.log(sb.toString());
+    }
+
+    static int pack2Bytes2Int(byte b1, byte b2) {
+        int out = 0x0;
+        out += b1;
+        out <<= 8;
+        out &= 0x0000ffff;
+        out |= 0x000000ff & b2;
+        return out;
+    }
+
+    static String paddedHexString(int n, int max) {
+        char[] c = Integer.toHexString(n).toCharArray();
+        char[] out = new char[max];
+
+        for (int i = 0; i < max; i++) {
+            out[i] = '0';
+        }
+        int offset = (max - c.length < 0) ? 0 : max - c.length;
+        for (int i = 0; i < c.length; i++) {
+            out[offset + i] = c[i];
+        }
+        return new String(out);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/sun/tools/pack/verify/JarFileCompare.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+package sun.tools.pack.verify;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+class JarFileCompare {
+    /*
+     * @author ksrini
+     */
+
+    private static VerifyTreeSet getVerifyTreeSet(String jarPath) {
+        VerifyTreeSet vts = new VerifyTreeSet();
+        try {
+            JarFile j = new JarFile(jarPath);
+            for (JarEntry je : Collections.list((Enumeration<JarEntry>) j.entries())) {
+                if (!je.isDirectory()) { // totally ignore directories
+                    vts.add(je.getName());
+                }
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+        return vts;
+    }
+
+    private static LinkedList getListOfClasses(String jarPath) {
+        LinkedList l = new LinkedList();
+        try {
+            JarFile j = new JarFile(jarPath);
+            for (JarEntry je : Collections.list((Enumeration<JarEntry>) j.entries())) {
+                if (!je.isDirectory() && je.getName().endsWith(".class")) {
+                    l.add(je.getName());
+                }
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+        return l;
+    }
+
+    private static void jarDirectoryCompare(String jarPath1, String jarPath2) {
+        VerifyTreeSet vts1 = getVerifyTreeSet(jarPath1);
+        VerifyTreeSet vts2 = getVerifyTreeSet(jarPath2);
+
+        TreeSet diff1 = vts1.diff(vts2);
+        if (diff1.size() > 0) {
+            Globals.log("Left has the following entries that right does not have");
+            Globals.log(diff1.toString());
+        }
+        TreeSet diff2 = vts2.diff(vts1);
+        if (diff2.size() > 0) {
+            Globals.log("Right has the following entries that left does not have");
+            Globals.log(diff2.toString());
+        }
+        if (Globals.checkJarClassOrdering()) {
+            boolean error = false;
+            Globals.println("Checking Class Ordering");
+            LinkedList l1 = getListOfClasses(jarPath1);
+            LinkedList l2 = getListOfClasses(jarPath2);
+            if (l1.size() != l2.size()) {
+                error = true;
+                Globals.log("The number of classes differs");
+                Globals.log("\t" + l1.size() + "<>" + l2.size());
+            }
+            for (int i = 0; i < l1.size(); i++) {
+                String s1 = (String) l1.get(i);
+                String s2 = (String) l2.get(i);
+                if (s1.compareTo(s2) != 0) {
+                    error = true;
+                    Globals.log("Ordering differs at[" + i + "] = " + s1);
+                    Globals.log("\t" + s2);
+                }
+            }
+        }
+    }
+
+    /*
+     * Returns true if the two Streams are bit identical, and false if they
+     * are not, no further diagnostics
+     */
+    static boolean compareStreams(InputStream is1, InputStream is2) {
+
+        BufferedInputStream bis1 = new BufferedInputStream(is1, 8192);
+        BufferedInputStream bis2 = new BufferedInputStream(is2, 8192);
+        try {
+            int i1, i2;
+            int count = 0;
+            while ((i1 = bis1.read()) == (i2 = bis2.read())) {
+                count++;
+                if (i1 < 0) {
+                    // System.out.println("bytes read " + count);
+                    return true;  // got all the way to EOF
+                }
+            }
+            return false;  // reads returned dif
+
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+
+    private static void checkEntry(JarFile jf1, JarFile jf2, JarEntry je) throws IOException {
+        InputStream is1 = jf1.getInputStream(je);
+        InputStream is2 = jf2.getInputStream(je);
+        if (is1 != null && is2 != null) {
+            if (!compareStreams(jf1.getInputStream(je), jf2.getInputStream(je))) {
+                Globals.println("+++" + je.getName() + "+++");
+                Globals.log("Error: File:" + je.getName()
+                        + " differs, use a diff util for further diagnostics");
+            }
+        } else {
+            Globals.println("+++" + je.getName() + "+++");
+            Globals.log("Error: File:" + je.getName() + " not found in " + jf2.getName());
+        }
+    }
+
+    /*
+     * Given two jar files we compare and see if the jarfiles have all the
+     * entries. The property ignoreJarDirectories is set to true by default
+     * which means that Directory entries in a jar may be ignore.
+     */
+    static void jarCompare(String jarPath1, String jarPath2) {
+        jarDirectoryCompare(jarPath1, jarPath2);
+
+        try {
+            JarFile jf1 = new JarFile(jarPath1);
+            JarFile jf2 = new JarFile(jarPath2);
+
+            int nclasses = 0;
+            int nentries = 0;
+            int entries_checked = 0;
+            int classes_checked = 0;
+
+            for (JarEntry je : Collections.list((Enumeration<JarEntry>) jf1.entries())) {
+                if (!je.isDirectory() && !je.getName().endsWith(".class")) {
+                    nentries++;
+                } else if (je.getName().endsWith(".class")) {
+                    nclasses++;
+                }
+            }
+
+            for (JarEntry je : Collections.list((Enumeration<JarEntry>) jf1.entries())) {
+                if (je.isDirectory()) {
+                    continue;  // Ignore directories
+                }
+                if (!je.getName().endsWith(".class")) {
+                    entries_checked++;
+                    if (je.getName().compareTo("META-INF/MANIFEST.MF") == 0) {
+                        Manifest mf1 = new Manifest(jf1.getInputStream(je));
+                        Manifest mf2 = new Manifest(jf2.getInputStream(je));
+                        if (!mf1.equals(mf2)) {
+                            Globals.log("Error: Manifests differ");
+                            Globals.log("Manifest1");
+                            Globals.log(mf1.getMainAttributes().entrySet().toString());
+                            Globals.log("Manifest2");
+                            Globals.log(mf2.getMainAttributes().entrySet().toString());
+                        }
+                    } else {
+                        checkEntry(jf1, jf2, je);
+                    }
+                } else if (Globals.bitWiseClassCompare() == true) {
+                    checkEntry(jf1, jf2, je);
+                    classes_checked++;
+                }
+            }
+            if (Globals.bitWiseClassCompare()) {
+                Globals.println("Class entries checked (byte wise)/Total Class entries = "
+                        + classes_checked + "/" + nclasses);
+            }
+            Globals.println("Non-class entries checked/Total non-class entries = "
+                    + entries_checked + "/" + nentries);
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/sun/tools/pack/verify/Main.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+// The Main Entry point
+package sun.tools.pack.verify;
+
+import java.io.*;
+
+/**
+ * This class provides a convenient entry point to the pack200 verifier. This
+ * compares two classes, either in path or in an archive.
+ * @see xmlkit.XMLKit
+ * @author ksrini
+ */
+public class Main {
+
+    private static void syntax() {
+        System.out.println("Usage: ");
+        System.out.println("\tREFERENCE_CLASSPATH COMPARED_CLASSPATH [Options]");
+        System.out.println("\tOptions:");
+        System.out.println("\t\t-O check jar ordering");
+        System.out.println("\t\t-C ignore compile attributes (Deprecated, SourceFile, Synthetic, )");
+        System.out.println("\t\t-D ignore debug attributes (LocalVariable, LineNumber)");
+        System.out.println("\t\t-u ignore unknown attributes");
+        System.out.println("\t\t-V turn off class validation");
+        System.out.println("\t\t-c CLASS, compare CLASS only");
+        System.out.println("\t\t-b Compares all entries bitwise only");
+        System.out.println("\t\t-l Directory or Log File Name");
+    }
+
+    /**
+     * main entry point to the class file comparator, which compares semantically
+     * class files in a classpath or an archive.
+     * @param args String array as described below
+     * @throws RuntimeException
+     * <pre>
+     *  Usage:
+     *     ReferenceClasspath SpecimenClaspath [Options]
+     *     Options:
+     *      -O check jar ordering
+     *      -C do not compare compile attributes (Deprecated, SourceFile, Synthetic)
+     *      -D do not compare debug attribute (LocalVariableTable, LineNumberTable)
+     *      -u ignore unknown attributes
+     *      -V turn off class validation
+     *      -c class, compare a single class
+     *      -b compares all entries bitwise (fastest)
+     *      -l directory or log file name
+     * </pre>
+     */
+    public static void main(String args[]) {
+        Globals.getInstance();
+        if (args == null || args.length < 2) {
+            syntax();
+            System.exit(1);
+        }
+        String refJarFileName = null;
+        String cmpJarFileName = null;
+        String specificClass = null;
+        String logDirFileName = null;
+
+        for (int i = 0; i < args.length; i++) {
+            if (i == 0) {
+                refJarFileName = args[0];
+                continue;
+            }
+            if (i == 1) {
+                cmpJarFileName = args[1];
+                continue;
+            }
+
+            if (args[i].startsWith("-O")) {
+                Globals.setCheckJarClassOrdering(true);
+            }
+
+            if (args[i].startsWith("-b")) {
+                Globals.setBitWiseClassCompare(true);
+            }
+
+            if (args[i].startsWith("-C")) {
+                Globals.setIgnoreCompileAttributes(true);
+            }
+
+            if (args[i].startsWith("-D")) {
+                Globals.setIgnoreDebugAttributes(true);
+            }
+
+            if (args[i].startsWith("-V")) {
+                Globals.setValidateClass(false);
+            }
+
+            if (args[i].startsWith("-c")) {
+                i++;
+                specificClass = args[i].trim();
+            }
+
+            if (args[i].startsWith("-u")) {
+                i++;
+                Globals.setIgnoreUnknownAttributes(true);
+            }
+
+            if (args[i].startsWith("-l")) {
+                i++;
+                logDirFileName = args[i].trim();
+            }
+        }
+
+        Globals.openLog(logDirFileName);
+
+        File refJarFile = new File(refJarFileName);
+        File cmpJarFile = new File(cmpJarFileName);
+
+        String f1 = refJarFile.getAbsoluteFile().toString();
+        String f2 = cmpJarFile.getAbsoluteFile().toString();
+
+        System.out.println("LogFile:" + Globals.getLogFileName());
+        System.out.println("Reference JAR:" + f1);
+        System.out.println("Compared  JAR:" + f2);
+
+        Globals.println("LogFile:" + Globals.getLogFileName());
+        Globals.println("Reference JAR:" + f1);
+        Globals.println("Compared  JAR:" + f2);
+
+        Globals.println("Ignore Compile Attributes:" + Globals.ignoreCompileAttributes());
+        Globals.println("Ignore Debug   Attributes:" + Globals.ignoreDebugAttributes());
+        Globals.println("Ignore Unknown Attributes:" + Globals.ignoreUnknownAttributes());
+        Globals.println("Class ordering check:" + Globals.checkJarClassOrdering());
+        Globals.println("Class validation check:" + Globals.validateClass());
+        Globals.println("Bit-wise compare:" + Globals.bitWiseClassCompare());
+        Globals.println("ClassName:" + ((specificClass == null) ? "ALL" : specificClass));
+
+        if (specificClass == null && Globals.bitWiseClassCompare() == true) {
+            JarFileCompare.jarCompare(refJarFileName, cmpJarFileName);
+        } else {
+            try {
+                ClassCompare.compareClass(refJarFileName, cmpJarFileName, specificClass);
+            } catch (Exception e) {
+                Globals.log("Exception " + e);
+                throw new RuntimeException(e);
+            }
+        }
+
+        if (Globals.getErrors() > 0) {
+            System.out.println("FAIL");
+            Globals.println("FAIL");
+            System.exit(Globals.getErrors());
+        }
+
+        System.out.println("PASS");
+        Globals.println("PASS");
+        System.exit(Globals.getErrors());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/sun/tools/pack/verify/VerifyTreeSet.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+package sun.tools.pack.verify;
+
+import java.util.*;
+/*
+ * @author ksrini
+ */
+
+class VerifyTreeSet<K> extends java.util.TreeSet {
+
+    VerifyTreeSet() {
+        super();
+    }
+
+    public VerifyTreeSet(Comparator c) {
+        super(c);
+    }
+
+    public TreeSet<K> diff(TreeSet in) {
+        TreeSet<K> delta = (TreeSet<K>) this.clone();
+        delta.removeAll(in);
+        return delta;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,1003 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+
+import java.util.*;
+import java.util.jar.*;
+import java.lang.reflect.*;
+import java.io.*;
+import xmlkit.XMLKit.Element;
+
+/*
+ * @author jrose
+ */
+public class ClassReader extends ClassSyntax {
+
+    private static final CommandLineParser CLP = new CommandLineParser(""
+            + "-source:     +> = \n"
+            + "-dest:       +> = \n"
+            + "-encoding:   +> = \n"
+            + "-jcov           $ \n   -nojcov         !-jcov        \n"
+            + "-verbose        $ \n   -noverbose      !-verbose     \n"
+            + "-pretty         $ \n   -nopretty       !-pretty      \n"
+            + "-keepPath       $ \n   -nokeepPath     !-keepPath    \n"
+            + "-keepCP         $ \n   -nokeepCP       !-keepCP      \n"
+            + "-keepBytes      $ \n   -nokeepBytes    !-keepBytes   \n"
+            + "-parseBytes     $ \n   -noparseBytes   !-parseBytes  \n"
+            + "-resolveRefs    $ \n   -noresolveRefs  !-resolveRefs \n"
+            + "-keepOrder      $ \n   -nokeepOrder    !-keepOrder   \n"
+            + "-keepSizes      $ \n   -nokeepSizes    !-keepSizes   \n"
+            + "-continue       $ \n   -nocontinue     !-continue    \n"
+            + "-attrDef        & \n"
+            + "-@         >-@  . \n"
+            + "-              +? \n"
+            + "\n");
+
+    public static void main(String[] ava) throws IOException {
+        ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
+        HashMap<String, String> props = new HashMap<String, String>();
+        props.put("-encoding:", "UTF8");  // default
+        props.put("-keepOrder", null);    // CLI default
+        props.put("-pretty", "1");     // CLI default
+        props.put("-continue", "1");     // CLI default
+        CLP.parse(av, props);
+        //System.out.println(props+" ++ "+av);
+        File source = asFile(props.get("-source:"));
+        File dest = asFile(props.get("-dest:"));
+        String encoding = props.get("-encoding:");
+        boolean contError = props.containsKey("-continue");
+        ClassReader options = new ClassReader();
+        options.copyOptionsFrom(props);
+        /*
+        if (dest == null && av.size() > 1) {
+        dest = File.createTempFile("TestOut", ".dir", new File("."));
+        dest.delete();
+        if (!dest.mkdir())
+        throw new RuntimeException("Cannot create "+dest);
+        System.out.println("Writing results to "+dest);
+        }
+         */
+        if (av.isEmpty()) {
+            av.add("doit");  //to enter this loop
+        }
+        boolean readList = false;
+        for (String a : av) {
+            if (readList) {
+                readList = false;
+                InputStream fin;
+                if (a.equals("-")) {
+                    fin = System.in;
+                } else {
+                    fin = new FileInputStream(a);
+                }
+
+                BufferedReader files = makeReader(fin, encoding);
+                for (String file; (file = files.readLine()) != null;) {
+                    doFile(file, source, dest, options, encoding, contError);
+                }
+                if (fin != System.in) {
+                    fin.close();
+                }
+            } else if (a.equals("-@")) {
+                readList = true;
+            } else if (a.startsWith("-")) {
+                throw new RuntimeException("Bad flag argument: " + a);
+            } else if (source.getName().endsWith(".jar")) {
+                doJar(a, source, dest, options, encoding, contError);
+            } else {
+                doFile(a, source, dest, options, encoding, contError);
+            }
+        }
+    }
+
+    private static File asFile(String str) {
+        return (str == null) ? null : new File(str);
+    }
+
+    private static void doFile(String a,
+            File source, File dest,
+            ClassReader options, String encoding,
+            boolean contError) throws IOException {
+        if (!contError) {
+            doFile(a, source, dest, options, encoding);
+        } else {
+            try {
+                doFile(a, source, dest, options, encoding);
+            } catch (Exception ee) {
+                System.out.println("Error processing " + source + ": " + ee);
+            }
+        }
+    }
+
+    private static void doJar(String a, File source, File dest, ClassReader options,
+            String encoding, Boolean contError) throws IOException {
+        try {
+            JarFile jf = new JarFile(source);
+            for (JarEntry je : Collections.list((Enumeration<JarEntry>) jf.entries())) {
+                String name = je.getName();
+                if (!name.endsWith(".class")) {
+                    continue;
+                }
+                doStream(name, jf.getInputStream(je), dest, options, encoding);
+            }
+        } catch (IOException ioe) {
+            if (contError) {
+                System.out.println("Error processing " + source + ": " + ioe);
+            } else {
+                throw ioe;
+            }
+        }
+    }
+
+    private static void doStream(String a, InputStream in, File dest,
+            ClassReader options, String encoding) throws IOException {
+
+        File f = new File(a);
+        ClassReader cr = new ClassReader(options);
+        Element e = cr.readFrom(in);
+
+        OutputStream out;
+        if (dest == null) {
+            //System.out.println(e.prettyString());
+            out = System.out;
+        } else {
+            File outf = new File(dest, f.isAbsolute() ? f.getName() : f.getPath());
+            String outName = outf.getName();
+            File outSubdir = outf.getParentFile();
+            outSubdir.mkdirs();
+            int extPos = outName.lastIndexOf('.');
+            if (extPos > 0) {
+                outf = new File(outSubdir, outName.substring(0, extPos) + ".xml");
+            }
+            out = new FileOutputStream(outf);
+        }
+
+        Writer outw = makeWriter(out, encoding);
+        if (options.pretty || !options.keepOrder) {
+            e.writePrettyTo(outw);
+        } else {
+            e.writeTo(outw);
+        }
+        if (out == System.out) {
+            outw.write("\n");
+            outw.flush();
+        } else {
+            outw.close();
+        }
+    }
+
+    private static void doFile(String a,
+            File source, File dest,
+            ClassReader options, String encoding) throws IOException {
+        File inf = new File(source, a);
+        if (dest != null && options.verbose) {
+            System.out.println("Reading " + inf);
+        }
+
+        BufferedInputStream in = new BufferedInputStream(new FileInputStream(inf));
+
+        doStream(a, in, dest, options, encoding);
+
+    }
+
+    public static BufferedReader makeReader(InputStream in, String encoding) throws IOException {
+        // encoding in DEFAULT, '', UTF8, 8BIT, , or any valid encoding name
+        if (encoding.equals("8BIT")) {
+            encoding = EIGHT_BIT_CHAR_ENCODING;
+        }
+        if (encoding.equals("UTF8")) {
+            encoding = UTF8_ENCODING;
+        }
+        if (encoding.equals("DEFAULT")) {
+            encoding = null;
+        }
+        if (encoding.equals("-")) {
+            encoding = null;
+        }
+        Reader inw;
+        in = new BufferedInputStream(in);  // add buffering
+        if (encoding == null) {
+            inw = new InputStreamReader(in);
+        } else {
+            inw = new InputStreamReader(in, encoding);
+        }
+        return new BufferedReader(inw);  // add buffering
+    }
+
+    public static Writer makeWriter(OutputStream out, String encoding) throws IOException {
+        // encoding in DEFAULT, '', UTF8, 8BIT, , or any valid encoding name
+        if (encoding.equals("8BIT")) {
+            encoding = EIGHT_BIT_CHAR_ENCODING;
+        }
+        if (encoding.equals("UTF8")) {
+            encoding = UTF8_ENCODING;
+        }
+        if (encoding.equals("DEFAULT")) {
+            encoding = null;
+        }
+        if (encoding.equals("-")) {
+            encoding = null;
+        }
+        Writer outw;
+        if (encoding == null) {
+            outw = new OutputStreamWriter(out);
+        } else {
+            outw = new OutputStreamWriter(out, encoding);
+        }
+        return new BufferedWriter(outw);  // add buffering
+    }
+
+    public Element result() {
+        return cfile;
+    }
+    protected InputStream in;
+    protected ByteArrayOutputStream buf = new ByteArrayOutputStream(1024);
+    protected byte cpTag[];
+    protected String cpName[];
+    protected String[] callables;     // varies
+    public static final String REF_PREFIX = "#";
+    // input options
+    public boolean pretty = false;
+    public boolean verbose = false;
+    public boolean keepPath = false;
+    public boolean keepCP = false;
+    public boolean keepBytes = false;
+    public boolean parseBytes = true;
+    public boolean resolveRefs = true;
+    public boolean keepOrder = true;
+    public boolean keepSizes = false;
+
+    public ClassReader() {
+        super.cfile = new Element("ClassFile");
+    }
+
+    public ClassReader(ClassReader options) {
+        this();
+        copyOptionsFrom(options);
+    }
+
+    public void copyOptionsFrom(ClassReader options) {
+        pretty = options.pretty;
+        verbose = options.verbose;
+        keepPath = options.keepPath;
+        keepCP = options.keepCP;
+        keepBytes = options.keepBytes;
+        parseBytes = options.parseBytes;
+        resolveRefs = options.resolveRefs;
+        keepSizes = options.keepSizes;
+        keepOrder = options.keepOrder;
+        attrTypes = options.attrTypes;
+    }
+
+    public void copyOptionsFrom(Map<String, String> options) {
+        if (options.containsKey("-pretty")) {
+            pretty = (options.get("-pretty") != null);
+        }
+        if (options.containsKey("-verbose")) {
+            verbose = (options.get("-verbose") != null);
+        }
+        if (options.containsKey("-keepPath")) {
+            keepPath = (options.get("-keepPath") != null);
+        }
+        if (options.containsKey("-keepCP")) {
+            keepCP = (options.get("-keepCP") != null);
+        }
+        if (options.containsKey("-keepBytes")) {
+            keepBytes = (options.get("-keepBytes") != null);
+        }
+        if (options.containsKey("-parseBytes")) {
+            parseBytes = (options.get("-parseBytes") != null);
+        }
+        if (options.containsKey("-resolveRefs")) {
+            resolveRefs = (options.get("-resolveRefs") != null);
+        }
+        if (options.containsKey("-keepSizes")) {
+            keepSizes = (options.get("-keepSizes") != null);
+        }
+        if (options.containsKey("-keepOrder")) {
+            keepOrder = (options.get("-keepOrder") != null);
+        }
+        if (options.containsKey("-attrDef")) {
+            addAttrTypes(options.get("-attrDef").split(" "));
+        }
+        if (options.get("-jcov") != null) {
+            addJcovAttrTypes();
+        }
+    }
+
+    public Element readFrom(InputStream in) throws IOException {
+        this.in = in;
+        // read the file header
+        int magic = u4();
+        if (magic != 0xCAFEBABE) {
+            throw new RuntimeException("bad magic number " + Integer.toHexString(magic));
+        }
+        cfile.setAttr("magic", "" + magic);
+        int minver = u2();
+        int majver = u2();
+        cfile.setAttr("minver", "" + minver);
+        cfile.setAttr("majver", "" + majver);
+        readCP();
+        readClass();
+        return result();
+    }
+
+    public Element readFrom(File file) throws IOException {
+        InputStream in = null;
+        try {
+            in = new FileInputStream(file);
+            Element e = readFrom(new BufferedInputStream(in));
+            if (keepPath) {
+                e.setAttr("path", file.toString());
+            }
+            return e;
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+        }
+    }
+
+    private void readClass() throws IOException {
+        klass = new Element("Class");
+        cfile.add(klass);
+        int flags = u2();
+        String thisk = cpRef();
+        String superk = cpRef();
+        klass.setAttr("name", thisk);
+        boolean flagsSync = ((flags & Modifier.SYNCHRONIZED) != 0);
+        flags &= ~Modifier.SYNCHRONIZED;
+        String flagString = flagString(flags, klass);
+        if (!flagsSync) {
+            if (flagString.length() > 0) {
+                flagString += " ";
+            }
+            flagString += "!synchronized";
+        }
+        klass.setAttr("flags", flagString);
+        klass.setAttr("super", superk);
+        for (int len = u2(), i = 0; i < len; i++) {
+            String interk = cpRef();
+            klass.add(new Element("Interface", "name", interk));
+        }
+        Element fields = readMembers("Field");
+        klass.addAll(fields);
+        Element methods = readMembers("Method");
+        if (!keepOrder) {
+            methods.sort();
+        }
+        klass.addAll(methods);
+        readAttributesFor(klass);
+        klass.trimToSize();
+        if (keepSizes) {
+            attachTo(cfile, formatAttrSizes());
+        }
+        if (paddingSize != 0) {
+            cfile.setAttr("padding", "" + paddingSize);
+        }
+    }
+
+    private Element readMembers(String kind) throws IOException {
+        int len = u2();
+        Element members = new Element(len);
+        for (int i = 0; i < len; i++) {
+            Element member = new Element(kind);
+            int flags = u2();
+            String name = cpRef();
+            String type = cpRef();
+            member.setAttr("name", name);
+            member.setAttr("type", type);
+            member.setAttr("flags", flagString(flags, member));
+            readAttributesFor(member);
+            member.trimToSize();
+            members.add(member);
+        }
+        return members;
+    }
+
+    protected String flagString(int flags, Element holder) {
+        // Superset of Modifier.toString.
+        int kind = 0;
+        if (holder.getName() == "Field") {
+            kind = 1;
+        }
+        if (holder.getName() == "Method") {
+            kind = 2;
+        }
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; flags != 0; i++, flags >>>= 1) {
+            if ((flags & 1) != 0) {
+                if (sb.length() > 0) {
+                    sb.append(' ');
+                }
+                if (i < modifierNames.length) {
+                    String[] names = modifierNames[i];
+                    String name = (kind < names.length) ? names[kind] : null;
+                    for (String name2 : names) {
+                        if (name != null) {
+                            break;
+                        }
+                        name = name2;
+                    }
+                    sb.append(name);
+                } else {
+                    sb.append("#").append(1 << i);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    private void readAttributesFor(Element x) throws IOException {
+        Element prevCurrent;
+        Element y = new Element();
+        if (x.getName() == "Code") {
+            prevCurrent = currentCode;
+            currentCode = x;
+        } else {
+            prevCurrent = currentMember;
+            currentMember = x;
+        }
+        for (int len = u2(), i = 0; i < len; i++) {
+            int ref = u2();
+            String uname = cpName(ref).intern();
+            String refName = uname;
+            if (!resolveRefs) {
+                refName = (REF_PREFIX + ref).intern();
+            }
+            String qname = (x.getName() + "." + uname).intern();
+            String wname = ("*." + uname).intern();
+            String type = attrTypes.get(qname);
+            if (type == null || "".equals(type)) {
+                type = attrTypes.get(wname);
+            }
+            if ("".equals(type)) {
+                type = null;
+            }
+            int size = u4();
+            int[] countVar = attrSizes.get(qname);
+            if (countVar == null) {
+                attrSizes.put(qname, countVar = new int[2]);
+            }
+            countVar[0] += 1;
+            countVar[1] += size;
+            buf.reset();
+            for (int j = 0; j < size; j++) {
+                buf.write(u1());
+            }
+            if (type == null && size == 0) {
+                y.add(new Element(uname)); // <Bridge>, etc.
+            } else if (type == null) {
+                //System.out.println("Warning:  No attribute type description: "+qname);
+                // write cdata attribute
+                Element a = new Element("Attribute",
+                        new String[]{"Name", refName},
+                        buf.toString(EIGHT_BIT_CHAR_ENCODING));
+                a.addContent(getCPDigest());
+                y.add(a);
+            } else if (type.equals("")) {
+                // ignore this attribute...
+            } else {
+                InputStream in0 = in;
+                int fileSize0 = fileSize;
+                ByteArrayInputStream in1 = new ByteArrayInputStream(buf.toByteArray());
+                boolean ok = false;
+                try {
+                    in = in1;
+                    // parse according to type desc.
+                    Element aval;
+                    if (type.equals("<Code>...")) {
+                        // delve into Code attribute
+                        aval = readCode();
+                    } else if (type.equals("<Frame>...")) {
+                        // delve into StackMap attribute
+                        aval = readStackMap(false);
+                    } else if (type.equals("<FrameX>...")) {
+                        // delve into StackMap attribute
+                        aval = readStackMap(true);
+                    } else if (type.startsWith("[")) {
+                        aval = readAttributeCallables(type);
+                    } else {
+                        aval = readAttribute(type);
+                    }
+                    //System.out.println("attachTo 1 "+y+" <- "+aval);
+                    attachTo(y, aval);
+                    if (false
+                            && in1.available() != 0) {
+                        throw new RuntimeException("extra bytes in " + qname + " :" + in1.available());
+                    }
+                    ok = true;
+                } finally {
+                    in = in0;
+                    fileSize = fileSize0;
+                    if (!ok) {
+                        System.out.println("*** Failed to read " + type);
+                    }
+                }
+            }
+        }
+        if (x.getName() == "Code") {
+            currentCode = prevCurrent;
+        } else {
+            currentMember = prevCurrent;
+        }
+        if (!keepOrder) {
+            y.sort();
+            y.sortAttrs();
+        }
+        //System.out.println("attachTo 2 "+x+" <- "+y);
+        attachTo(x, y);
+    }
+    private int fileSize = 0;
+    private int paddingSize = 0;
+    private HashMap<String, int[]> attrSizes = new HashMap<String, int[]>();
+
+    private Element formatAttrSizes() {
+        Element e = new Element("Sizes");
+        e.setAttr("fileSize", "" + fileSize);
+        for (Map.Entry<String, int[]> ie : attrSizes.entrySet()) {
+            int[] countVar = ie.getValue();
+            e.add(new Element("AttrSize",
+                    "name", ie.getKey().toString(),
+                    "count", "" + countVar[0],
+                    "size", "" + countVar[1]));
+        }
+        return e;
+    }
+
+    private void attachTo(Element x, Object aval0) {
+        if (aval0 == null) {
+            return;
+        }
+        //System.out.println("attachTo "+x+" : "+aval0);
+        if (!(aval0 instanceof Element)) {
+            x.add(aval0);
+            return;
+        }
+        Element aval = (Element) aval0;
+        if (!aval.isAnonymous()) {
+            x.add(aval);
+            return;
+        }
+        for (int imax = aval.attrSize(), i = 0; i < imax; i++) {
+            //%%
+            attachAttrTo(x, aval.getAttrName(i), aval.getAttr(i));
+        }
+        x.addAll(aval);
+    }
+
+    private void attachAttrTo(Element x, String aname, String aval) {
+        //System.out.println("attachAttrTo "+x+" : "+aname+"="+aval);
+        String aval0 = x.getAttr(aname);
+        if (aval0 != null) {
+            aval = aval0 + " " + aval;
+        }
+        x.setAttr(aname, aval);
+    }
+
+    private Element readAttributeCallables(String type) throws IOException {
+        assert (callables == null);
+        callables = getBodies(type);
+        Element res = readAttribute(callables[0]);
+        callables = null;
+        return res;
+    }
+
+    private Element readAttribute(String type) throws IOException {
+        //System.out.println("readAttribute "+type);
+        Element aval = new Element();
+        String nextAttrName = null;
+        for (int len = type.length(), next, i = 0; i < len; i = next) {
+            String value;
+            switch (type.charAt(i)) {
+                case '<':
+                    assert (nextAttrName == null);
+                    next = type.indexOf('>', ++i);
+                    String form = type.substring(i, next++);
+                    if (form.indexOf('=') < 0) {
+                        //  elem_placement = '<' elemname '>'
+                        assert (aval.attrSize() == 0);
+                        assert (aval.isAnonymous());
+                        aval.setName(form.intern());
+                    } else {
+                        //  attr_placement = '<' attrname '=' (value)? '>'
+                        int eqPos = form.indexOf('=');
+                        nextAttrName = form.substring(0, eqPos).intern();
+                        if (eqPos != form.length() - 1) {
+                            value = form.substring(eqPos + 1);
+                            attachAttrTo(aval, nextAttrName, value);
+                            nextAttrName = null;
+                        }
+                        // ...else subsequent type parsing will find the attr value
+                        // and add it as "nextAttrName".
+                    }
+                    continue;
+                case '(':
+                    next = type.indexOf(')', ++i);
+                    int callee = Integer.parseInt(type.substring(i, next++));
+                    attachTo(aval, readAttribute(callables[callee]));
+                    continue;
+                case 'N': // replication = 'N' int '[' type ... ']'
+                {
+                    int count = getInt(type.charAt(i + 1), false);
+                    assert (count >= 0);
+                    next = i + 2;
+                    String type1 = getBody(type, next);
+                    next += type1.length() + 2;  // skip body and brackets
+                    for (int j = 0; j < count; j++) {
+                        attachTo(aval, readAttribute(type1));
+                    }
+                }
+                continue;
+                case 'T': // union = 'T' any_int union_case* '(' ')' '[' body ']'
+                    int tagValue;
+                    if (type.charAt(++i) == 'S') {
+                        tagValue = getInt(type.charAt(++i), true);
+                    } else {
+                        tagValue = getInt(type.charAt(i), false);
+                    }
+                    attachAttrTo(aval, "tag", "" + tagValue);  // always named "tag"
+                    ++i;  // skip the int type char
+                    // union_case = '(' uc_tag (',' uc_tag)* ')' '[' body ']'
+                    // uc_tag = ('-')? digit+
+                    for (boolean foundCase = false;; i = next) {
+                        assert (type.charAt(i) == '(');
+                        next = type.indexOf(')', ++i);
+                        assert (next >= i);
+                        if (type.charAt(next - 1) == '\\'
+                                && type.charAt(next - 2) != '\\') // Skip an escaped paren.
+                        {
+                            next = type.indexOf(')', next + 1);
+                        }
+                        String caseStr = type.substring(i, next++);
+                        String type1 = getBody(type, next);
+                        next += type1.length() + 2;  // skip body and brackets
+                        boolean lastCase = (caseStr.length() == 0);
+                        if (!foundCase
+                                && (lastCase || matchTag(tagValue, caseStr))) {
+                            foundCase = true;
+                            // Execute this body.
+                            attachTo(aval, readAttribute(type1));
+                        }
+                        if (lastCase) {
+                            break;
+                        }
+                    }
+                    continue;
+                case 'B':
+                case 'H':
+                case 'I': // int = oneof "BHI"
+                    next = i + 1;
+                    value = "" + getInt(type.charAt(i), false);
+                    break;
+                case 'K':
+                    assert ("IJFDLQ".indexOf(type.charAt(i + 1)) >= 0);
+                    assert (type.charAt(i + 2) == 'H');  // only H works for now
+                    next = i + 3;
+                    value = cpRef();
+                    break;
+                case 'R':
+                    assert ("CSDFMIU?".indexOf(type.charAt(i + 1)) >= 0);
+                    assert (type.charAt(i + 2) == 'H');  // only H works for now
+                    next = i + 3;
+                    value = cpRef();
+                    break;
+                case 'P':  // bci = 'P' int
+                    next = i + 2;
+                    value = "" + getInt(type.charAt(i + 1), false);
+                    break;
+                case 'S':  // signed_int = 'S' int
+                    next = i + 2;
+                    value = "" + getInt(type.charAt(i + 1), true);
+                    break;
+                case 'F':
+                    next = i + 2;
+                    value = flagString(getInt(type.charAt(i + 1), false), currentMember);
+                    break;
+                default:
+                    throw new RuntimeException("bad attr format '" + type.charAt(i) + "': " + type);
+            }
+            // store the value
+            if (nextAttrName != null) {
+                attachAttrTo(aval, nextAttrName, value);
+                nextAttrName = null;
+            } else {
+                attachTo(aval, value);
+            }
+        }
+        //System.out.println("readAttribute => "+aval);
+        assert (nextAttrName == null);
+        return aval;
+    }
+
+    private int getInt(char ch, boolean signed) throws IOException {
+        if (signed) {
+            switch (ch) {
+                case 'B':
+                    return (byte) u1();
+                case 'H':
+                    return (short) u2();
+                case 'I':
+                    return (int) u4();
+            }
+        } else {
+            switch (ch) {
+                case 'B':
+                    return u1();
+                case 'H':
+                    return u2();
+                case 'I':
+                    return u4();
+            }
+        }
+        assert ("BHIJ".indexOf(ch) >= 0);
+        return 0;
+    }
+
+    private Element readCode() throws IOException {
+        int stack = u2();
+        int local = u2();
+        int length = u4();
+        StringBuilder sb = new StringBuilder(length);
+        for (int i = 0; i < length; i++) {
+            sb.append((char) u1());
+        }
+        String bytecodes = sb.toString();
+        Element e = new Element("Code",
+                "stack", "" + stack,
+                "local", "" + local);
+        Element bytes = new Element("Bytes", (String[]) null, bytecodes);
+        if (keepBytes) {
+            e.add(bytes);
+        }
+        if (parseBytes) {
+            e.add(parseByteCodes(bytecodes));
+        }
+        for (int len = u2(), i = 0; i < len; i++) {
+            int start = u2();
+            int end = u2();
+            int catsh = u2();
+            String clasz = cpRef();
+            e.add(new Element("Handler",
+                    "start", "" + start,
+                    "end", "" + end,
+                    "catch", "" + catsh,
+                    "class", clasz));
+        }
+        readAttributesFor(e);
+        e.trimToSize();
+        return e;
+    }
+
+    private Element parseByteCodes(String bytecodes) {
+        Element e = InstructionSyntax.parse(bytecodes);
+        for (Element ins : e.elements()) {
+            Number ref = ins.getAttrNumber("ref");
+            if (ref != null && resolveRefs) {
+                int id = ref.intValue();
+                String val = cpName(id);
+                if (ins.getName().startsWith("ldc")) {
+                    // Yuck:  Arb. string cannot be an XML attribute.
+                    ins.add(val);
+                    val = "";
+                    byte tag = (id >= 0 && id < cpTag.length) ? cpTag[id] : 0;
+                    if (tag != 0) {
+                        ins.setAttrLong("tag", tag);
+                    }
+                }
+                if (ins.getName() == "invokeinterface"
+                        && computeInterfaceNum(val) == ins.getAttrLong("num")) {
+                    ins.setAttr("num", null);  // garbage bytes
+                }
+                ins.setAttr("ref", null);
+                ins.setAttr("val", val);
+            }
+        }
+        return e;
+    }
+
+    private Element readStackMap(boolean hasXOption) throws IOException {
+        Element result = new Element();
+        Element bytes = currentCode.findElement("Bytes");
+        assert (bytes != null && bytes.size() == 1);
+        int byteLength = ((String) bytes.get(0)).length();
+        boolean uoffsetIsU4 = (byteLength >= (1 << 16));
+        boolean ulocalvarIsU4 = currentCode.getAttrLong("local") >= (1 << 16);
+        boolean ustackIsU4 = currentCode.getAttrLong("stack") >= (1 << 16);
+        if (hasXOption || uoffsetIsU4 || ulocalvarIsU4 || ustackIsU4) {
+            Element flags = new Element("StackMapFlags");
+            if (hasXOption) {
+                flags.setAttr("hasXOption", "true");
+            }
+            if (uoffsetIsU4) {
+                flags.setAttr("uoffsetIsU4", "true");
+            }
+            if (ulocalvarIsU4) {
+                flags.setAttr("ulocalvarIsU4", "true");
+            }
+            if (ustackIsU4) {
+                flags.setAttr("ustackIsU4", "true");
+            }
+            currentCode.add(flags);
+        }
+        int frame_count = (uoffsetIsU4 ? u4() : u2());
+        for (int i = 0; i < frame_count; i++) {
+            int bci = (uoffsetIsU4 ? u4() : u2());
+            int flags = (hasXOption ? u1() : 0);
+            Element frame = new Element("Frame");
+            result.add(frame);
+            if (flags != 0) {
+                frame.setAttr("flags", "" + flags);
+            }
+            frame.setAttr("bci", "" + bci);
+            // Scan local and stack types in this frame:
+            final int LOCALS = 0, STACK = 1;
+            for (int j = LOCALS; j <= STACK; j++) {
+                int typeSize;
+                if (j == LOCALS) {
+                    typeSize = (ulocalvarIsU4 ? u4() : u2());
+                } else { // STACK
+                    typeSize = (ustackIsU4 ? u4() : u2());
+                }
+                Element types = new Element(j == LOCALS ? "Local" : "Stack");
+                for (int k = 0; k < typeSize; k++) {
+                    int tag = u1();
+                    Element type = new Element(itemTagName(tag));
+                    types.add(type);
+                    switch (tag) {
+                        case ITEM_Object:
+                            type.setAttr("class", cpRef());
+                            break;
+                        case ITEM_Uninitialized:
+                        case ITEM_ReturnAddress:
+                            type.setAttr("bci", "" + (uoffsetIsU4 ? u4() : u2()));
+                            break;
+                    }
+                }
+                if (types.size() > 0) {
+                    frame.add(types);
+                }
+            }
+        }
+        return result;
+    }
+
+    private void readCP() throws IOException {
+        int cpLen = u2();
+        cpTag = new byte[cpLen];
+        cpName = new String[cpLen];
+        int cpTem[][] = new int[cpLen][];
+        for (int i = 1; i < cpLen; i++) {
+            cpTag[i] = (byte) u1();
+            switch (cpTag[i]) {
+                case CONSTANT_Utf8:
+                    buf.reset();
+                    for (int len = u2(), j = 0; j < len; j++) {
+                        buf.write(u1());
+                    }
+                    cpName[i] = buf.toString(UTF8_ENCODING);
+                    break;
+                case CONSTANT_Integer:
+                    cpName[i] = String.valueOf((int) u4());
+                    break;
+                case CONSTANT_Float:
+                    cpName[i] = String.valueOf(Float.intBitsToFloat(u4()));
+                    break;
+                case CONSTANT_Long:
+                    cpName[i] = String.valueOf(u8());
+                    i += 1;
+                    break;
+                case CONSTANT_Double:
+                    cpName[i] = String.valueOf(Double.longBitsToDouble(u8()));
+                    i += 1;
+                    break;
+                case CONSTANT_Class:
+                case CONSTANT_String:
+                    cpTem[i] = new int[]{u2()};
+                    break;
+                case CONSTANT_Fieldref:
+                case CONSTANT_Methodref:
+                case CONSTANT_InterfaceMethodref:
+                case CONSTANT_NameAndType:
+                    cpTem[i] = new int[]{u2(), u2()};
+                    break;
+            }
+        }
+        for (int i = 1; i < cpLen; i++) {
+            switch (cpTag[i]) {
+                case CONSTANT_Class:
+                case CONSTANT_String:
+                    cpName[i] = cpName[cpTem[i][0]];
+                    break;
+                case CONSTANT_NameAndType:
+                    cpName[i] = cpName[cpTem[i][0]] + " " + cpName[cpTem[i][1]];
+                    break;
+            }
+        }
+        // do fieldref et al after nameandtype are all resolved
+        for (int i = 1; i < cpLen; i++) {
+            switch (cpTag[i]) {
+                case CONSTANT_Fieldref:
+                case CONSTANT_Methodref:
+                case CONSTANT_InterfaceMethodref:
+                    cpName[i] = cpName[cpTem[i][0]] + " " + cpName[cpTem[i][1]];
+                    break;
+            }
+        }
+        cpool = new Element("ConstantPool", cpName.length);
+        for (int i = 0; i < cpName.length; i++) {
+            if (cpName[i] == null) {
+                continue;
+            }
+            cpool.add(new Element(cpTagName(cpTag[i]),
+                    new String[]{"id", "" + i},
+                    cpName[i]));
+        }
+        if (keepCP) {
+            cfile.add(cpool);
+        }
+    }
+
+    private String cpRef() throws IOException {
+        int ref = u2();
+        if (resolveRefs) {
+            return cpName(ref);
+        } else {
+            return REF_PREFIX + ref;
+        }
+    }
+
+    private String cpName(int id) {
+        if (id >= 0 && id < cpName.length) {
+            return cpName[id];
+        } else {
+            return "[CP#" + Integer.toHexString(id) + "]";
+        }
+    }
+
+    private long u8() throws IOException {
+        return ((long) u4() << 32) + (((long) u4() << 32) >>> 32);
+    }
+
+    private int u4() throws IOException {
+        return (u2() << 16) + u2();
+    }
+
+    private int u2() throws IOException {
+        return (u1() << 8) + u1();
+    }
+
+    private int u1() throws IOException {
+        int x = in.read();
+        if (x < 0) {
+            paddingSize++;
+            return 0;  // error recovery
+        }
+        fileSize++;
+        assert (x == (x & 0xFF));
+        return x;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassSyntax.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+import xmlkit.XMLKit.*;
+
+import java.util.*;
+import java.security.MessageDigest;
+import java.nio.ByteBuffer;
+import xmlkit.XMLKit.Element;
+/*
+ * @author jrose
+ */
+public abstract class ClassSyntax {
+
+    public interface GetCPIndex {
+
+        int getCPIndex(int tag, String name);  // cp finder
+    }
+    public static final int CONSTANT_Utf8 = 1,
+            CONSTANT_Integer = 3,
+            CONSTANT_Float = 4,
+            CONSTANT_Long = 5,
+            CONSTANT_Double = 6,
+            CONSTANT_Class = 7,
+            CONSTANT_String = 8,
+            CONSTANT_Fieldref = 9,
+            CONSTANT_Methodref = 10,
+            CONSTANT_InterfaceMethodref = 11,
+            CONSTANT_NameAndType = 12;
+    private static final String[] cpTagName = {
+        /* 0:  */null,
+        /* 1:  */ "Utf8",
+        /* 2:  */ null,
+        /* 3:  */ "Integer",
+        /* 4:  */ "Float",
+        /* 5:  */ "Long",
+        /* 6:  */ "Double",
+        /* 7:  */ "Class",
+        /* 8:  */ "String",
+        /* 9:  */ "Fieldref",
+        /* 10: */ "Methodref",
+        /* 11: */ "InterfaceMethodref",
+        /* 12: */ "NameAndType",
+        null
+    };
+    private static final Set<String> cpTagNames;
+
+    static {
+        Set<String> set = new HashSet<String>(Arrays.asList(cpTagName));
+        set.remove(null);
+        cpTagNames = Collections.unmodifiableSet(set);
+    }
+    public static final int ITEM_Top = 0, // replicates by [1..4,1..4]
+            ITEM_Integer = 1, // (ditto)
+            ITEM_Float = 2,
+            ITEM_Double = 3,
+            ITEM_Long = 4,
+            ITEM_Null = 5,
+            ITEM_UninitializedThis = 6,
+            ITEM_Object = 7,
+            ITEM_Uninitialized = 8,
+            ITEM_ReturnAddress = 9,
+            ITEM_LIMIT = 10;
+    private static final String[] itemTagName = {
+        "Top",
+        "Integer",
+        "Float",
+        "Double",
+        "Long",
+        "Null",
+        "UninitializedThis",
+        "Object",
+        "Uninitialized",
+        "ReturnAddress",};
+    private static final Set<String> itemTagNames;
+
+    static {
+        Set<String> set = new HashSet<String>(Arrays.asList(itemTagName));
+        set.remove(null);
+        itemTagNames = Collections.unmodifiableSet(set);
+    }
+    protected static final HashMap<String, String> attrTypesBacking;
+    protected static final Map<String, String> attrTypesInit;
+
+    static {
+        HashMap<String, String> at = new HashMap<String, String>();
+
+        //at.put("*.Deprecated", "<deprecated=true>");
+        //at.put("*.Synthetic", "<synthetic=true>");
+        ////at.put("Field.ConstantValue", "<constantValue=>KQH");
+        //at.put("Class.SourceFile", "<sourceFile=>RUH");
+        at.put("Method.Bridge", "<Bridge>");
+        at.put("Method.Varargs", "<Varargs>");
+        at.put("Class.Enum", "<Enum>");
+        at.put("*.Signature", "<Signature>RSH");
+        //at.put("*.Deprecated", "<Deprecated>");
+        //at.put("*.Synthetic", "<Synthetic>");
+        at.put("Field.ConstantValue", "<ConstantValue>KQH");
+        at.put("Class.SourceFile", "<SourceFile>RUH");
+        at.put("Class.InnerClasses", "NH[<InnerClass><class=>RCH<outer=>RCH<name=>RUH<flags=>FH]");
+        at.put("Code.LineNumberTable", "NH[<LineNumber><bci=>PH<line=>H]");
+        at.put("Code.LocalVariableTable", "NH[<LocalVariable><bci=>PH<span=>H<name=>RUH<type=>RSH<slot=>H]");
+        at.put("Code.LocalVariableTypeTable", "NH[<LocalVariableType><bci=>PH<span=>H<name=>RUH<type=>RSH<slot=>H]");
+        at.put("Method.Exceptions", "NH[<Exception><name=>RCH]");
+        at.put("Method.Code", "<Code>...");
+        at.put("Code.StackMapTable", "<Frame>...");
+        //at.put("Code.StkMapX", "<FrameX>...");
+        if (true) {
+            at.put("Code.StackMapTable",
+                    "[NH[<Frame>(1)]]"
+                    + "[TB"
+                    + "(64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79"
+                    + ",80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95"
+                    + ",96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111"
+                    + ",112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127"
+                    + ")[<SameLocals1StackItemFrame>(4)]"
+                    + "(247)[<SameLocals1StackItemExtended>H(4)]"
+                    + "(248)[<Chop3>H]"
+                    + "(249)[<Chop2>H]"
+                    + "(250)[<Chop1>H]"
+                    + "(251)[<SameFrameExtended>H]"
+                    + "(252)[<Append1>H(4)]"
+                    + "(253)[<Append2>H(4)(4)]"
+                    + "(254)[<Append3>H(4)(4)(4)]"
+                    + "(255)[<FullFrame>H(2)(3)]"
+                    + "()[<SameFrame>]]"
+                    + "[NH[<Local>(4)]]"
+                    + "[NH[<Stack>(4)]]"
+                    + "[TB"
+                    + ("(0)[<Top>]"
+                    + "(1)[<ItemInteger>](2)[<ItemFloat>](3)[<ItemDouble>](4)[<ItemLong>]"
+                    + "(5)[<ItemNull>](6)[<ItemUninitializedThis>]"
+                    + "(7)[<ItemObject><class=>RCH]"
+                    + "(8)[<ItemUninitialized><bci=>PH]"
+                    + "()[<ItemUnknown>]]"));
+        }
+
+        at.put("Class.EnclosingMethod", "<EnclosingMethod><class=>RCH<desc=>RDH");//RDNH
+
+        // Layouts of metadata attrs:
+        String vpf = "[<RuntimeVisibleAnnotation>";
+        String ipf = "[<RuntimeInvisibleAnnotation>";
+        String apf = "[<Annotation>";
+        String mdanno2 = ""
+                + "<type=>RSHNH[<Member><name=>RUH(3)]]"
+                + ("[TB"
+                + "(\\B,\\C,\\I,\\S,\\Z)[<value=>KIH]"
+                + "(\\D)[<value=>KDH]"
+                + "(\\F)[<value=>KFH]"
+                + "(\\J)[<value=>KJH]"
+                + "(\\c)[<class=>RSH]"
+                + "(\\e)[<type=>RSH<name=>RUH]"
+                + "(\\s)[<String>RUH]"
+                + "(\\@)[(2)]"
+                + "(\\[)[NH[<Element>(3)]]"
+                + "()[]"
+                + "]");
+        String visanno = "[NH[(2)]][(1)]" + vpf + mdanno2;
+        String invanno = "[NH[(2)]][(1)]" + ipf + mdanno2;
+        String vparamanno = ""
+                + "[NB[<RuntimeVisibleParameterAnnotation>(1)]][NH[(2)]]"
+                + apf + mdanno2;
+        String iparamanno = ""
+                + "[NB[<RuntimeInvisibleParameterAnnotation>(1)]][NH[(2)]]"
+                + apf + mdanno2;
+        String mdannodef = "[<AnnotationDefault>(3)][(1)]" + apf + mdanno2;
+        String[] mdplaces = {"Class", "Field", "Method"};
+        for (String place : mdplaces) {
+            at.put(place + ".RuntimeVisibleAnnotations", visanno);
+            at.put(place + ".RuntimeInvisibleAnnotations", invanno);
+        }
+        at.put("Method.RuntimeVisibleParameterAnnotations", vparamanno);
+        at.put("Method.RuntimeInvisibleParameterAnnotations", iparamanno);
+        at.put("Method.AnnotationDefault", mdannodef);
+
+        attrTypesBacking = at;
+        attrTypesInit = Collections.unmodifiableMap(at);
+    }
+
+    ;
+    private static final String[] jcovAttrTypes = {
+        "Code.CoverageTable=NH[<Coverage><bci=>PH<type=>H<line=>I<pos=>I]",
+        "Code.CharacterRangeTable=NH[<CharacterRange><bci=>PH<endbci=>POH<from=>I<to=>I<flag=>H]",
+        "Class.SourceID=<SourceID><id=>RUH",
+        "Class.CompilationID=<CompilationID><id=>RUH"
+    };
+    protected static final String[][] modifierNames = {
+        {"public"},
+        {"private"},
+        {"protected"},
+        {"static"},
+        {"final"},
+        {"synchronized"},
+        {null, "volatile", "bridge"},
+        {null, "transient", "varargs"},
+        {null, null, "native"},
+        {"interface"},
+        {"abstract"},
+        {"strictfp"},
+        {"synthetic"},
+        {"annotation"},
+        {"enum"},};
+    protected static final String EIGHT_BIT_CHAR_ENCODING = "ISO8859_1";
+    protected static final String UTF8_ENCODING = "UTF8";
+    // What XML tags are used by this syntax, apart from attributes?
+    protected static final Set<String> nonAttrTags;
+
+    static {
+        HashSet<String> tagSet = new HashSet<String>();
+        Collections.addAll(tagSet, new String[]{
+                    "ConstantPool",// the CP
+                    "Class", // the class
+                    "Interface", // implemented interfaces
+                    "Method", // methods
+                    "Field", // fields
+                    "Handler", // exception handler pseudo-attribute
+                    "Attribute", // unparsed attribute
+                    "Bytes", // bytecodes
+                    "Instructions" // bytecodes, parsed
+                });
+        nonAttrTags = Collections.unmodifiableSet(tagSet);
+    }
+
+    // Accessors.
+    public static Set<String> nonAttrTags() {
+        return nonAttrTags;
+    }
+
+    public static String cpTagName(int t) {
+        t &= 0xFF;
+        String ts = null;
+        if (t < cpTagName.length) {
+            ts = cpTagName[t];
+        }
+        if (ts != null) {
+            return ts;
+        }
+        return ("UnknownTag" + (int) t).intern();
+    }
+
+    public static int cpTagValue(String name) {
+        for (int t = 0; t < cpTagName.length; t++) {
+            if (name.equals(cpTagName[t])) {
+                return t;
+            }
+        }
+        return 0;
+    }
+
+    public static String itemTagName(int t) {
+        t &= 0xFF;
+        String ts = null;
+        if (t < itemTagName.length) {
+            ts = itemTagName[t];
+        }
+        if (ts != null) {
+            return ts;
+        }
+        return ("UnknownItem" + (int) t).intern();
+    }
+
+    public static int itemTagValue(String name) {
+        for (int t = 0; t < itemTagName.length; t++) {
+            if (name.equals(itemTagName[t])) {
+                return t;
+            }
+        }
+        return -1;
+    }
+
+    public void addJcovAttrTypes() {
+        addAttrTypes(jcovAttrTypes);
+    }
+    // Public methods for declaring attribute types.
+    protected Map<String, String> attrTypes = attrTypesInit;
+
+    public void addAttrType(String opt) {
+        int eqpos = opt.indexOf('=');
+        addAttrType(opt.substring(0, eqpos), opt.substring(eqpos + 1));
+    }
+
+    public void addAttrTypes(String[] opts) {
+        for (String opt : opts) {
+            addAttrType(opt);
+        }
+    }
+
+    private void checkAttr(String attr) {
+        if (!attr.startsWith("Class.")
+                && !attr.startsWith("Field.")
+                && !attr.startsWith("Method.")
+                && !attr.startsWith("Code.")
+                && !attr.startsWith("*.")) {
+            throw new IllegalArgumentException("attr name must start with 'Class.', etc.");
+        }
+        String uattr = attr.substring(attr.indexOf('.') + 1);
+        if (nonAttrTags.contains(uattr)) {
+            throw new IllegalArgumentException("attr name must not be one of " + nonAttrTags);
+        }
+    }
+
+    private void checkAttrs(Map<String, String> at) {
+        for (String attr : at.keySet()) {
+            checkAttr(attr);
+        }
+    }
+
+    private void modAttrs() {
+        if (attrTypes == attrTypesInit) {
+            // Make modifiable.
+            attrTypes = new HashMap<String, String>(attrTypesBacking);
+        }
+    }
+
+    public void addAttrType(String attr, String fmt) {
+        checkAttr(attr);
+        modAttrs();
+        attrTypes.put(attr, fmt);
+    }
+
+    public void addAttrTypes(Map<String, String> at) {
+        checkAttrs(at);
+        modAttrs();
+        attrTypes.putAll(at);
+    }
+
+    public Map<String, String> getAttrTypes() {
+        if (attrTypes == attrTypesInit) {
+            return attrTypes;
+        }
+        return Collections.unmodifiableMap(attrTypes);
+    }
+
+    public void setAttrTypes(Map<String, String> at) {
+        checkAttrs(at);
+        modAttrs();
+        attrTypes.keySet().retainAll(at.keySet());
+        attrTypes.putAll(at);
+    }
+
+    // attr format helpers
+    protected static boolean matchTag(int tagValue, String caseStr) {
+        //System.out.println("matchTag "+tagValue+" in "+caseStr);
+        for (int pos = 0, max = caseStr.length(), comma;
+                pos < max;
+                pos = comma + 1) {
+            int caseValue;
+            if (caseStr.charAt(pos) == '\\') {
+                caseValue = caseStr.charAt(pos + 1);
+                comma = pos + 2;
+                assert (comma == max || caseStr.charAt(comma) == ',');
+            } else {
+                comma = caseStr.indexOf(',', pos);
+                if (comma < 0) {
+                    comma = max;
+                }
+                caseValue = Integer.parseInt(caseStr.substring(pos, comma));
+            }
+            if (tagValue == caseValue) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected static String[] getBodies(String type) {
+        ArrayList<String> bodies = new ArrayList<String>();
+        for (int i = 0; i < type.length();) {
+            String body = getBody(type, i);
+            bodies.add(body);
+            i += body.length() + 2;  // skip body and brackets
+        }
+        return bodies.toArray(new String[bodies.size()]);
+    }
+
+    protected static String getBody(String type, int i) {
+        assert (type.charAt(i) == '[');
+        int next = ++i;  // skip bracket
+        for (int depth = 1; depth > 0; next++) {
+            switch (type.charAt(next)) {
+                case '[':
+                    depth++;
+                    break;
+                case ']':
+                    depth--;
+                    break;
+                case '(':
+                    next = type.indexOf(')', next);
+                    break;
+                case '<':
+                    next = type.indexOf('>', next);
+                    break;
+            }
+            assert (next > 0);
+        }
+        --next;  // get before bracket
+        assert (type.charAt(next) == ']');
+        return type.substring(i, next);
+    }
+
+    public Element makeCPDigest(int length) {
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance("MD5");
+        } catch (java.security.NoSuchAlgorithmException ee) {
+            throw new Error(ee);
+        }
+        int items = 0;
+        for (Element e : cpool.elements()) {
+            if (items == length) {
+                break;
+            }
+            if (cpTagNames.contains(e.getName())) {
+                items += 1;
+                md.update((byte) cpTagValue(e.getName()));
+                try {
+                    md.update(e.getText().toString().getBytes(UTF8_ENCODING));
+                } catch (java.io.UnsupportedEncodingException ee) {
+                    throw new Error(ee);
+                }
+            }
+        }
+        ByteBuffer bb = ByteBuffer.wrap(md.digest());
+        String l0 = Long.toHexString(bb.getLong(0));
+        String l1 = Long.toHexString(bb.getLong(8));
+        while (l0.length() < 16) {
+            l0 = "0" + l0;
+        }
+        while (l1.length() < 16) {
+            l1 = "0" + l1;
+        }
+        return new Element("Digest",
+                "length", "" + items,
+                "bytes", l0 + l1);
+    }
+
+    public Element getCPDigest(int length) {
+        if (length == -1) {
+            length = cpool.countAll(XMLKit.elementFilter(cpTagNames));
+        }
+        for (Element md : cpool.findAllElements("Digest").elements()) {
+            if (md.getAttrLong("length") == length) {
+                return md;
+            }
+        }
+        Element md = makeCPDigest(length);
+        cpool.add(md);
+        return md;
+    }
+
+    public Element getCPDigest() {
+        return getCPDigest(-1);
+    }
+
+    public boolean checkCPDigest(Element md) {
+        return md.equals(getCPDigest((int) md.getAttrLong("length")));
+    }
+
+    public static int computeInterfaceNum(String intMethRef) {
+        intMethRef = intMethRef.substring(1 + intMethRef.lastIndexOf(' '));
+        if (!intMethRef.startsWith("(")) {
+            return -1;
+        }
+        int signum = 1;  // start with one for "this"
+        scanSig:
+        for (int i = 1; i < intMethRef.length(); i++) {
+            char ch = intMethRef.charAt(i);
+            signum++;
+            switch (ch) {
+                case ')':
+                    --signum;
+                    break scanSig;
+                case 'L':
+                    i = intMethRef.indexOf(';', i);
+                    break;
+                case '[':
+                    while (ch == '[') {
+                        ch = intMethRef.charAt(++i);
+                    }
+                    if (ch == 'L') {
+                        i = intMethRef.indexOf(';', i);
+                    }
+                    break;
+            }
+        }
+        int num = (signum << 8) | 0;
+        //System.out.println("computeInterfaceNum "+intMethRef+" => "+num);
+        return num;
+    }
+    // Protected state for representing the class file.
+    protected Element cfile;          // <ClassFile ...>
+    protected Element cpool;          // <ConstantPool ...>
+    protected Element klass;          // <Class ...>
+    protected Element currentMember;  // varies during scans
+    protected Element currentCode;    // varies during scans
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassWriter.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,818 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+
+import java.util.*;
+import java.lang.reflect.*;
+import java.io.*;
+import xmlkit.XMLKit.Element;
+/*
+ * @author jrose
+ */
+public class ClassWriter extends ClassSyntax implements ClassSyntax.GetCPIndex {
+
+    private static final CommandLineParser CLP = new CommandLineParser(""
+            + "-source:     +>  = \n"
+            + "-dest:       +>  = \n"
+            + "-encoding:   +>  = \n"
+            + "-parseBytes      $ \n"
+            + "-               *? \n"
+            + "\n");
+
+    public static void main(String[] ava) throws IOException {
+        ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
+        HashMap<String, String> props = new HashMap<String, String>();
+        props.put("-encoding:", "UTF8");  // default
+        CLP.parse(av, props);
+        File source = asFile(props.get("-source:"));
+        File dest = asFile(props.get("-dest:"));
+        String encoding = props.get("-encoding:");
+        boolean parseBytes = props.containsKey("-parseBytes");
+        boolean destMade = false;
+
+        for (String a : av) {
+            File f;
+            File inf = new File(source, a);
+            System.out.println("Reading " + inf);
+            Element e;
+            if (inf.getName().endsWith(".class")) {
+                ClassReader cr = new ClassReader();
+                cr.parseBytes = parseBytes;
+                e = cr.readFrom(inf);
+                f = new File(a);
+            } else if (inf.getName().endsWith(".xml")) {
+                InputStream in = new FileInputStream(inf);
+                Reader inw = ClassReader.makeReader(in, encoding);
+                e = XMLKit.readFrom(inw);
+                e.findAllInTree(XMLKit.and(XMLKit.elementFilter(nonAttrTags()),
+                        XMLKit.methodFilter(Element.method("trimText"))));
+                //System.out.println(e);
+                inw.close();
+                f = new File(a.substring(0, a.length() - ".xml".length()) + ".class");
+            } else {
+                System.out.println("Warning: unknown input " + a);
+                continue;
+            }
+            // Now write it:
+            if (!destMade) {
+                destMade = true;
+                if (dest == null) {
+                    dest = File.createTempFile("TestOut", ".dir", new File("."));
+                    dest.delete();
+                    System.out.println("Writing results to " + dest);
+                }
+                if (!(dest.isDirectory() || dest.mkdir())) {
+                    throw new RuntimeException("Cannot create " + dest);
+                }
+            }
+            File outf = new File(dest, f.isAbsolute() ? f.getName() : f.getPath());
+            outf.getParentFile().mkdirs();
+            new ClassWriter(e).writeTo(outf);
+        }
+    }
+
+    private static File asFile(String str) {
+        return (str == null) ? null : new File(str);
+    }
+
+    public void writeTo(File file) throws IOException {
+        OutputStream out = null;
+        try {
+            out = new BufferedOutputStream(new FileOutputStream(file));
+            writeTo(out);
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+    protected String[] callables;     // varies
+    protected int cpoolSize = 0;
+    protected HashMap<String, String> attrTypesByTag;
+    protected OutputStream out;
+    protected HashMap<String, int[]> cpMap = new HashMap<String, int[]>();
+    protected ArrayList<ByteArrayOutputStream> attrBufs = new ArrayList<ByteArrayOutputStream>();
+
+    private void setupAttrTypes() {
+        attrTypesByTag = new HashMap<String, String>();
+        for (String key : attrTypes.keySet()) {
+            String pfx = key.substring(0, key.indexOf('.') + 1);
+            String val = attrTypes.get(key);
+            int pos = val.indexOf('<');
+            if (pos >= 0) {
+                String tag = val.substring(pos + 1, val.indexOf('>', pos));
+                attrTypesByTag.put(pfx + tag, key);
+            }
+        }
+        //System.out.println("attrTypesByTag: "+attrTypesByTag);
+    }
+
+    protected ByteArrayOutputStream getAttrBuf() {
+        int nab = attrBufs.size();
+        if (nab == 0) {
+            return new ByteArrayOutputStream(1024);
+        }
+        ByteArrayOutputStream ab = attrBufs.get(nab - 1);
+        attrBufs.remove(nab - 1);
+        return ab;
+    }
+
+    protected void putAttrBuf(ByteArrayOutputStream ab) {
+        ab.reset();
+        attrBufs.add(ab);
+    }
+
+    public ClassWriter(Element root) {
+        this(root, null);
+    }
+
+    public ClassWriter(Element root, ClassSyntax cr) {
+        if (cr != null) {
+            attrTypes = cr.attrTypes;
+        }
+        setupAttrTypes();
+        if (root.getName() == "ClassFile") {
+            cfile = root;
+            cpool = root.findElement("ConstantPool");
+            klass = root.findElement("Class");
+        } else if (root.getName() == "Class") {
+            cfile = new Element("ClassFile",
+                    new String[]{
+                        "magic", String.valueOf(0xCAFEBABE),
+                        "minver", "0", "majver", "46",});
+            cpool = new Element("ConstantPool");
+            klass = root;
+        } else {
+            throw new IllegalArgumentException("bad element type " + root.getName());
+        }
+        if (cpool == null) {
+            cpool = new Element("ConstantPool");
+        }
+
+        int cpLen = 1 + cpool.size();
+        for (Element c : cpool.elements()) {
+            int id = (int) c.getAttrLong("id");
+            int tag = cpTagValue(c.getName());
+            setCPIndex(tag, c.getText().toString(), id);
+            switch (tag) {
+                case CONSTANT_Long:
+                case CONSTANT_Double:
+                    cpLen += 1;
+            }
+        }
+        cpoolSize = cpLen;
+    }
+
+    public int findCPIndex(int tag, String name) {
+        if (name == null) {
+            return 0;
+        }
+        int[] ids = cpMap.get(name.toString());
+        return (ids == null) ? 0 : ids[tag];
+    }
+
+    public int getCPIndex(int tag, String name) {
+        //System.out.println("getCPIndex "+cpTagName(tag)+" "+name);
+        if (name == null) {
+            return 0;
+        }
+        int id = findCPIndex(tag, name);
+        if (id == 0) {
+            id = cpoolSize;
+            cpoolSize += 1;
+            setCPIndex(tag, name, id);
+            cpool.add(new Element(cpTagName(tag),
+                    new String[]{"id", "" + id},
+                    new Object[]{name}));
+            int pos;
+            switch (tag) {
+                case CONSTANT_Long:
+                case CONSTANT_Double:
+                    cpoolSize += 1;
+                    break;
+                case CONSTANT_Class:
+                case CONSTANT_String:
+                    getCPIndex(CONSTANT_Utf8, name);
+                    break;
+                case CONSTANT_Fieldref:
+                case CONSTANT_Methodref:
+                case CONSTANT_InterfaceMethodref:
+                    pos = name.indexOf(' ');
+                    getCPIndex(CONSTANT_Class, name.substring(0, pos));
+                    getCPIndex(CONSTANT_NameAndType, name.substring(pos + 1));
+                    break;
+                case CONSTANT_NameAndType:
+                    pos = name.indexOf(' ');
+                    getCPIndex(CONSTANT_Utf8, name.substring(0, pos));
+                    getCPIndex(CONSTANT_Utf8, name.substring(pos + 1));
+                    break;
+            }
+        }
+        return id;
+    }
+
+    public void setCPIndex(int tag, String name, int id) {
+        //System.out.println("setCPIndex id="+id+" tag="+tag+" name="+name);
+        int[] ids = cpMap.get(name);
+        if (ids == null) {
+            cpMap.put(name, ids = new int[13]);
+        }
+        if (ids[tag] != 0 && ids[tag] != id) {
+            System.out.println("Warning: Duplicate CP entries for " + ids[tag] + " and " + id);
+        }
+        //assert(ids[tag] == 0 || ids[tag] == id);
+        ids[tag] = id;
+    }
+
+    public int parseFlags(String flagString) {
+        int flags = 0;
+        int i = -1;
+        for (String[] names : modifierNames) {
+            ++i;
+            for (String name : names) {
+                if (name == null) {
+                    continue;
+                }
+                int pos = flagString.indexOf(name);
+                if (pos >= 0) {
+                    flags |= (1 << i);
+                }
+            }
+        }
+        return flags;
+    }
+
+    public void writeTo(OutputStream realOut) throws IOException {
+        OutputStream headOut = realOut;
+        ByteArrayOutputStream tailOut = new ByteArrayOutputStream();
+
+        // write the body of the class file first
+        this.out = tailOut;
+        writeClass();
+
+        // write the file header last
+        this.out = headOut;
+        u4((int) cfile.getAttrLong("magic"));
+        u2((int) cfile.getAttrLong("minver"));
+        u2((int) cfile.getAttrLong("majver"));
+        writeCP();
+
+        // recopy the file tail
+        this.out = null;
+        tailOut.writeTo(realOut);
+    }
+
+    void writeClass() throws IOException {
+        int flags = parseFlags(klass.getAttr("flags"));
+        flags ^= Modifier.SYNCHRONIZED;
+        u2(flags);
+        cpRef(CONSTANT_Class, klass.getAttr("name"));
+        cpRef(CONSTANT_Class, klass.getAttr("super"));
+        Element interfaces = klass.findAllElements("Interface");
+        u2(interfaces.size());
+        for (Element e : interfaces.elements()) {
+            cpRef(CONSTANT_Class, e.getAttr("name"));
+        }
+        for (int isMethod = 0; isMethod <= 1; isMethod++) {
+            Element members = klass.findAllElements(isMethod != 0 ? "Method" : "Field");
+            u2(members.size());
+            for (Element m : members.elements()) {
+                writeMember(m, isMethod != 0);
+            }
+        }
+        writeAttributesFor(klass);
+    }
+
+    private void writeMember(Element member, boolean isMethod) throws IOException {
+        //System.out.println("writeMember "+member);
+        u2(parseFlags(member.getAttr("flags")));
+        cpRef(CONSTANT_Utf8, member.getAttr("name"));
+        cpRef(CONSTANT_Utf8, member.getAttr("type"));
+        writeAttributesFor(member);
+    }
+
+    protected void writeAttributesFor(Element x) throws IOException {
+        LinkedHashSet<String> attrNames = new LinkedHashSet<String>();
+        for (Element e : x.elements()) {
+            attrNames.add(e.getName());  // uniquifying
+        }
+        attrNames.removeAll(nonAttrTags());
+        u2(attrNames.size());
+        if (attrNames.isEmpty()) {
+            return;
+        }
+        Element prevCurrent;
+        if (x.getName() == "Code") {
+            prevCurrent = currentCode;
+            currentCode = x;
+        } else {
+            prevCurrent = currentMember;
+            currentMember = x;
+        }
+        OutputStream realOut = this.out;
+        for (String utag : attrNames) {
+            String qtag = x.getName() + "." + utag;
+            String wtag = "*." + utag;
+            String key = attrTypesByTag.get(qtag);
+            if (key == null) {
+                key = attrTypesByTag.get(wtag);
+            }
+            String type = attrTypes.get(key);
+            //System.out.println("tag "+qtag+" => key "+key+"; type "+type);
+            Element attrs = x.findAllElements(utag);
+            ByteArrayOutputStream attrBuf = getAttrBuf();
+            if (type == null) {
+                if (attrs.size() != 1 || !attrs.get(0).equals(new Element(utag))) {
+                    System.out.println("Warning:  No attribute type description: " + qtag);
+                }
+                key = wtag;
+            } else {
+                try {
+                    this.out = attrBuf;
+                    // unparse according to type desc.
+                    if (type.equals("<Code>...")) {
+                        writeCode((Element) attrs.get(0));  // assume only 1
+                    } else if (type.equals("<Frame>...")) {
+                        writeStackMap(attrs, false);
+                    } else if (type.equals("<FrameX>...")) {
+                        writeStackMap(attrs, true);
+                    } else if (type.startsWith("[")) {
+                        writeAttributeRecursive(attrs, type);
+                    } else {
+                        writeAttribute(attrs, type);
+                    }
+                } finally {
+                    //System.out.println("Attr Bytes = \""+attrBuf.toString(EIGHT_BIT_CHAR_ENCODING).replace('"', (char)('"'|0x80))+"\"");
+                    this.out = realOut;
+                }
+            }
+            cpRef(CONSTANT_Utf8, key.substring(key.indexOf('.') + 1));
+            u4(attrBuf.size());
+            attrBuf.writeTo(out);
+            putAttrBuf(attrBuf);
+        }
+        if (x.getName() == "Code") {
+            currentCode = prevCurrent;
+        } else {
+            currentMember = prevCurrent;
+        }
+    }
+
+    private void writeAttributeRecursive(Element aval, String type) throws IOException {
+        assert (callables == null);
+        callables = getBodies(type);
+        writeAttribute(aval, callables[0]);
+        callables = null;
+    }
+
+    private void writeAttribute(Element aval, String type) throws IOException {
+        //System.out.println("writeAttribute "+aval+"  using "+type);
+        String nextAttrName = null;
+        boolean afterElemHead = false;
+        for (int len = type.length(), next, i = 0; i < len; i = next) {
+            int value;
+            char intKind;
+            int tag;
+            int sigChar;
+            String attrValue;
+            switch (type.charAt(i)) {
+                case '<':
+                    assert (nextAttrName == null);
+                    next = type.indexOf('>', i);
+                    String form = type.substring(i + 1, next++);
+                    if (form.indexOf('=') < 0) {
+                        //  elem_placement = '<' elemname '>'
+                        if (aval.isAnonymous()) {
+                            assert (aval.size() == 1);
+                            aval = (Element) aval.get(0);
+                        }
+                        assert (aval.getName().equals(form)) : aval + " // " + form;
+                        afterElemHead = true;
+                    } else {
+                        //  attr_placement = '(' attrname '=' (value)? ')'
+                        int eqPos = form.indexOf('=');
+                        assert (eqPos >= 0);
+                        nextAttrName = form.substring(0, eqPos).intern();
+                        if (eqPos != form.length() - 1) {
+                            // value is implicit, not placed in file
+                            nextAttrName = null;
+                        }
+                        afterElemHead = false;
+                    }
+                    continue;
+                case '(':
+                    next = type.indexOf(')', ++i);
+                    int callee = Integer.parseInt(type.substring(i, next++));
+                    writeAttribute(aval, callables[callee]);
+                    continue;
+                case 'N': // replication = 'N' int '[' type ... ']'
+                {
+                    assert (nextAttrName == null);
+                    afterElemHead = false;
+                    char countType = type.charAt(i + 1);
+                    next = i + 2;
+                    String type1 = getBody(type, next);
+                    Element elems = aval;
+                    if (type1.startsWith("<")) {
+                        // Select only matching members of aval.
+                        String elemName = type1.substring(1, type1.indexOf('>'));
+                        elems = aval.findAllElements(elemName);
+                    }
+                    putInt(elems.size(), countType);
+                    next += type1.length() + 2;  // skip body and brackets
+                    for (Element elem : elems.elements()) {
+                        writeAttribute(elem, type1);
+                    }
+                }
+                continue;
+                case 'T': // union = 'T' any_int union_case* '(' ')' '[' body ']'
+                    // write the value
+                    value = (int) aval.getAttrLong("tag");
+                    assert (aval.getAttr("tag") != null) : aval;
+                    intKind = type.charAt(++i);
+                    if (intKind == 'S') {
+                        intKind = type.charAt(++i);
+                    }
+                    putInt(value, intKind);
+                    nextAttrName = null;
+                    afterElemHead = false;
+                    ++i;  // skip the int type char
+                    // union_case = '(' ('-')? digit+ ')' '[' body ']'
+                    for (boolean foundCase = false;;) {
+                        assert (type.charAt(i) == '(');
+                        next = type.indexOf(')', ++i);
+                        assert (next >= i);
+                        String caseStr = type.substring(i, next++);
+                        String type1 = getBody(type, next);
+                        next += type1.length() + 2;  // skip body and brackets
+                        boolean lastCase = (caseStr.length() == 0);
+                        if (!foundCase
+                                && (lastCase || matchTag(value, caseStr))) {
+                            foundCase = true;
+                            // Execute this body.
+                            writeAttribute(aval, type1);
+                        }
+                        if (lastCase) {
+                            break;
+                        }
+                    }
+                    continue;
+                case 'B':
+                case 'H':
+                case 'I': // int = oneof "BHI"
+                    value = (int) aval.getAttrLong(nextAttrName);
+                    intKind = type.charAt(i);
+                    next = i + 1;
+                    break;
+                case 'K':
+                    sigChar = type.charAt(i + 1);
+                    if (sigChar == 'Q') {
+                        assert (currentMember.getName() == "Field");
+                        assert (aval.getName() == "ConstantValue");
+                        String sig = currentMember.getAttr("type");
+                        sigChar = sig.charAt(0);
+                        switch (sigChar) {
+                            case 'Z':
+                            case 'B':
+                            case 'C':
+                            case 'S':
+                                sigChar = 'I';
+                                break;
+                        }
+                    }
+                    switch (sigChar) {
+                        case 'I':
+                            tag = CONSTANT_Integer;
+                            break;
+                        case 'J':
+                            tag = CONSTANT_Long;
+                            break;
+                        case 'F':
+                            tag = CONSTANT_Float;
+                            break;
+                        case 'D':
+                            tag = CONSTANT_Double;
+                            break;
+                        case 'L':
+                            tag = CONSTANT_String;
+                            break;
+                        default:
+                            assert (false);
+                            tag = 0;
+                    }
+                    assert (type.charAt(i + 2) == 'H');  // only H works for now
+                    next = i + 3;
+                    assert (afterElemHead || nextAttrName != null);
+                    //System.out.println("get attr "+nextAttrName+" in "+aval);
+                    if (nextAttrName != null) {
+                        attrValue = aval.getAttr(nextAttrName);
+                        assert (attrValue != null);
+                    } else {
+                        assert (aval.isText()) : aval;
+                        attrValue = aval.getText().toString();
+                    }
+                    value = getCPIndex(tag, attrValue);
+                    intKind = 'H'; //type.charAt(i+2);
+                    break;
+                case 'R':
+                    sigChar = type.charAt(i + 1);
+                    switch (sigChar) {
+                        case 'C':
+                            tag = CONSTANT_Class;
+                            break;
+                        case 'S':
+                            tag = CONSTANT_Utf8;
+                            break;
+                        case 'D':
+                            tag = CONSTANT_Class;
+                            break;
+                        case 'F':
+                            tag = CONSTANT_Fieldref;
+                            break;
+                        case 'M':
+                            tag = CONSTANT_Methodref;
+                            break;
+                        case 'I':
+                            tag = CONSTANT_InterfaceMethodref;
+                            break;
+                        case 'U':
+                            tag = CONSTANT_Utf8;
+                            break;
+                        //case 'Q': tag = CONSTANT_Class; break;
+                        default:
+                            assert (false);
+                            tag = 0;
+                    }
+                    assert (type.charAt(i + 2) == 'H');  // only H works for now
+                    next = i + 3;
+                    assert (afterElemHead || nextAttrName != null);
+                    //System.out.println("get attr "+nextAttrName+" in "+aval);
+                    if (nextAttrName != null) {
+                        attrValue = aval.getAttr(nextAttrName);
+                    } else if (aval.hasText()) {
+                        attrValue = aval.getText().toString();
+                    } else {
+                        attrValue = null;
+                    }
+                    value = getCPIndex(tag, attrValue);
+                    intKind = 'H'; //type.charAt(i+2);
+                    break;
+                case 'P':  // bci = 'P' int
+                case 'S':  // signed_int = 'S' int
+                    next = i + 2;
+                    value = (int) aval.getAttrLong(nextAttrName);
+                    intKind = type.charAt(i + 1);
+                    break;
+                case 'F':
+                    next = i + 2;
+                    value = parseFlags(aval.getAttr(nextAttrName));
+                    intKind = type.charAt(i + 1);
+                    break;
+                default:
+                    throw new RuntimeException("bad attr format '" + type.charAt(i) + "': " + type);
+            }
+            // write the value
+            putInt(value, intKind);
+            nextAttrName = null;
+            afterElemHead = false;
+        }
+        assert (nextAttrName == null);
+    }
+
+    private void putInt(int x, char ch) throws IOException {
+        switch (ch) {
+            case 'B':
+                u1(x);
+                break;
+            case 'H':
+                u2(x);
+                break;
+            case 'I':
+                u4(x);
+                break;
+        }
+        assert ("BHI".indexOf(ch) >= 0);
+    }
+
+    private void writeCode(Element code) throws IOException {
+        //System.out.println("writeCode "+code);
+        //Element m = new Element(currentMember); m.remove(code);
+        //System.out.println("       in "+m);
+        int stack = (int) code.getAttrLong("stack");
+        int local = (int) code.getAttrLong("local");
+        Element bytes = code.findElement("Bytes");
+        Element insns = code.findElement("Instructions");
+        String bytecodes;
+        if (insns == null) {
+            bytecodes = bytes.getText().toString();
+        } else {
+            bytecodes = InstructionSyntax.assemble(insns, this);
+            // Cache the assembled bytecodes:
+            bytes = new Element("Bytes", (String[]) null, bytecodes);
+            code.add(0, bytes);
+        }
+        u2(stack);
+        u2(local);
+        int length = bytecodes.length();
+        u4(length);
+        for (int i = 0; i < length; i++) {
+            u1((byte) bytecodes.charAt(i));
+        }
+        Element handlers = code.findAllElements("Handler");
+        u2(handlers.size());
+        for (Element handler : handlers.elements()) {
+            int start = (int) handler.getAttrLong("start");
+            int end = (int) handler.getAttrLong("end");
+            int catsh = (int) handler.getAttrLong("catch");
+            u2(start);
+            u2(end);
+            u2(catsh);
+            cpRef(CONSTANT_Class, handler.getAttr("class"));
+        }
+        writeAttributesFor(code);
+    }
+
+    protected void writeStackMap(Element attrs, boolean hasXOption) throws IOException {
+        Element bytes = currentCode.findElement("Bytes");
+        assert (bytes != null && bytes.size() == 1);
+        int byteLength = ((String) bytes.get(0)).length();
+        boolean uoffsetIsU4 = (byteLength >= (1 << 16));
+        boolean ulocalvarIsU4 = currentCode.getAttrLong("local") >= (1 << 16);
+        boolean ustackIsU4 = currentCode.getAttrLong("stack") >= (1 << 16);
+        if (uoffsetIsU4) {
+            u4(attrs.size());
+        } else {
+            u2(attrs.size());
+        }
+        for (Element frame : attrs.elements()) {
+            int bci = (int) frame.getAttrLong("bci");
+            if (uoffsetIsU4) {
+                u4(bci);
+            } else {
+                u2(bci);
+            }
+            if (hasXOption) {
+                u1((int) frame.getAttrLong("flags"));
+            }
+            // Scan local and stack types in this frame:
+            final int LOCALS = 0, STACK = 1;
+            for (int j = LOCALS; j <= STACK; j++) {
+                Element types = frame.findElement(j == LOCALS ? "Local" : "Stack");
+                int typeSize = (types == null) ? 0 : types.size();
+                if (j == LOCALS) {
+                    if (ulocalvarIsU4) {
+                        u4(typeSize);
+                    } else {
+                        u2(typeSize);
+                    }
+                } else { // STACK
+                    if (ustackIsU4) {
+                        u4(typeSize);
+                    } else {
+                        u2(typeSize);
+                    }
+                }
+                if (types == null) {
+                    continue;
+                }
+                for (Element type : types.elements()) {
+                    int tag = itemTagValue(type.getName());
+                    u1(tag);
+                    switch (tag) {
+                        case ITEM_Object:
+                            cpRef(CONSTANT_Class, type.getAttr("class"));
+                            break;
+                        case ITEM_Uninitialized:
+                        case ITEM_ReturnAddress: {
+                            int offset = (int) type.getAttrLong("bci");
+                            if (uoffsetIsU4) {
+                                u4(offset);
+                            } else {
+                                u2(offset);
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    public void writeCP() throws IOException {
+        int cpLen = cpoolSize;
+        u2(cpLen);
+        ByteArrayOutputStream buf = getAttrBuf();
+        for (Element c : cpool.elements()) {
+            if (!c.isText()) {
+                System.out.println("## !isText " + c);
+            }
+            int id = (int) c.getAttrLong("id");
+            int tag = cpTagValue(c.getName());
+            String name = c.getText().toString();
+            int pos;
+            u1(tag);
+            switch (tag) {
+                case CONSTANT_Utf8: {
+                    int done = 0;
+                    buf.reset();
+                    int nameLen = name.length();
+                    while (done < nameLen) {
+                        int next = name.indexOf((char) 0, done);
+                        if (next < 0) {
+                            next = nameLen;
+                        }
+                        if (done < next) {
+                            buf.write(name.substring(done, next).getBytes(UTF8_ENCODING));
+                        }
+                        if (next < nameLen) {
+                            buf.write(0300);
+                            buf.write(0200);
+                            next++;
+                        }
+                        done = next;
+                    }
+                    u2(buf.size());
+                    buf.writeTo(out);
+                }
+                break;
+                case CONSTANT_Integer:
+                    u4(Integer.parseInt(name));
+                    break;
+                case CONSTANT_Float:
+                    u4(Float.floatToIntBits(Float.parseFloat(name)));
+                    break;
+                case CONSTANT_Long:
+                    u8(Long.parseLong(name));
+                    //i += 1;  // no need:  extra cp slot is implicit
+                    break;
+                case CONSTANT_Double:
+                    u8(Double.doubleToLongBits(Double.parseDouble(name)));
+                    //i += 1;  // no need:  extra cp slot is implicit
+                    break;
+                case CONSTANT_Class:
+                case CONSTANT_String:
+                    u2(getCPIndex(CONSTANT_Utf8, name));
+                    break;
+                case CONSTANT_Fieldref:
+                case CONSTANT_Methodref:
+                case CONSTANT_InterfaceMethodref:
+                    pos = name.indexOf(' ');
+                    u2(getCPIndex(CONSTANT_Class, name.substring(0, pos)));
+                    u2(getCPIndex(CONSTANT_NameAndType, name.substring(pos + 1)));
+                    break;
+                case CONSTANT_NameAndType:
+                    pos = name.indexOf(' ');
+                    u2(getCPIndex(CONSTANT_Utf8, name.substring(0, pos)));
+                    u2(getCPIndex(CONSTANT_Utf8, name.substring(pos + 1)));
+                    break;
+            }
+        }
+        putAttrBuf(buf);
+    }
+
+    public void cpRef(int tag, String name) throws IOException {
+        u2(getCPIndex(tag, name));
+    }
+
+    public void u8(long x) throws IOException {
+        u4((int) (x >>> 32));
+        u4((int) (x >>> 0));
+    }
+
+    public void u4(int x) throws IOException {
+        u2(x >>> 16);
+        u2(x >>> 0);
+    }
+
+    public void u2(int x) throws IOException {
+        u1(x >>> 8);
+        u1(x >>> 0);
+    }
+
+    public void u1(int x) throws IOException {
+        out.write(x & 0xFF);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/CommandLineParser.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+
+import java.util.*;
+/*
+ * @author jrose
+ */
+public class CommandLineParser {
+
+    public CommandLineParser(String optionString) {
+        setOptionMap(optionString);
+    }
+    TreeMap<String, String[]> optionMap;
+
+    public void setOptionMap(String options) {
+        // Convert options string into optLines dictionary.
+        TreeMap<String, String[]> optmap = new TreeMap<String, String[]>();
+        loadOptmap:
+        for (String optline : options.split("\n")) {
+            String[] words = optline.split("\\p{Space}+");
+            if (words.length == 0) {
+                continue loadOptmap;
+            }
+            String opt = words[0];
+            words[0] = "";  // initial word is not a spec
+            if (opt.length() == 0 && words.length >= 1) {
+                opt = words[1];  // initial "word" is empty due to leading ' '
+                words[1] = "";
+            }
+            if (opt.length() == 0) {
+                continue loadOptmap;
+            }
+            String[] prevWords = optmap.put(opt, words);
+            if (prevWords != null) {
+                throw new RuntimeException("duplicate option: "
+                        + optline.trim());
+            }
+        }
+        optionMap = optmap;
+    }
+
+    public String getOptionMap() {
+        TreeMap<String, String[]> optmap = optionMap;
+        StringBuffer sb = new StringBuffer();
+        for (String opt : optmap.keySet()) {
+            sb.append(opt);
+            for (String spec : optmap.get(opt)) {
+                sb.append(' ').append(spec);
+            }
+            sb.append('\n');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Remove a set of command-line options from args,
+     * storing them in the properties map in a canonicalized form.
+     */
+    public String parse(List<String> args, Map<String, String> properties) {
+        //System.out.println(args+" // "+properties);
+
+        String resultString = null;
+        TreeMap<String, String[]> optmap = optionMap;
+
+        // State machine for parsing a command line.
+        ListIterator<String> argp = args.listIterator();
+        ListIterator<String> pbp = new ArrayList<String>().listIterator();
+        doArgs:
+        for (;;) {
+            // One trip through this loop per argument.
+            // Multiple trips per option only if several options per argument.
+            String arg;
+            if (pbp.hasPrevious()) {
+                arg = pbp.previous();
+                pbp.remove();
+            } else if (argp.hasNext()) {
+                arg = argp.next();
+            } else {
+                // No more arguments at all.
+                break doArgs;
+            }
+            tryOpt:
+            for (int optlen = arg.length();; optlen--) {
+                // One time through this loop for each matching arg prefix.
+                String opt;
+                // Match some prefix of the argument to a key in optmap.
+                findOpt:
+                for (;;) {
+                    opt = arg.substring(0, optlen);
+                    if (optmap.containsKey(opt)) {
+                        break findOpt;
+                    }
+                    if (optlen == 0) {
+                        break tryOpt;
+                    }
+                    // Decide on a smaller prefix to search for.
+                    SortedMap<String, String[]> pfxmap = optmap.headMap(opt);
+                    // pfxmap.lastKey is no shorter than any prefix in optmap.
+                    int len = pfxmap.isEmpty() ? 0 : pfxmap.lastKey().length();
+                    optlen = Math.min(len, optlen - 1);
+                    opt = arg.substring(0, optlen);
+                    // (Note:  We could cut opt down to its common prefix with
+                    // pfxmap.lastKey, but that wouldn't save many cycles.)
+                }
+                opt = opt.intern();
+                assert (arg.startsWith(opt));
+                assert (opt.length() == optlen);
+                String val = arg.substring(optlen);  // arg == opt+val
+
+                // Execute the option processing specs for this opt.
+                // If no actions are taken, then look for a shorter prefix.
+                boolean didAction = false;
+                boolean isError = false;
+
+                int pbpMark = pbp.nextIndex();  // in case of backtracking
+                String[] specs = optmap.get(opt);
+                eachSpec:
+                for (String spec : specs) {
+                    if (spec.length() == 0) {
+                        continue eachSpec;
+                    }
+                    if (spec.startsWith("#")) {
+                        break eachSpec;
+                    }
+                    int sidx = 0;
+                    char specop = spec.charAt(sidx++);
+
+                    // Deal with '+'/'*' prefixes (spec conditions).
+                    boolean ok;
+                    switch (specop) {
+                        case '+':
+                            // + means we want an non-empty val suffix.
+                            ok = (val.length() != 0);
+                            specop = spec.charAt(sidx++);
+                            break;
+                        case '*':
+                            // * means we accept empty or non-empty
+                            ok = true;
+                            specop = spec.charAt(sidx++);
+                            break;
+                        default:
+                            // No condition prefix means we require an exact
+                            // match, as indicated by an empty val suffix.
+                            ok = (val.length() == 0);
+                            break;
+                    }
+                    if (!ok) {
+                        continue eachSpec;
+                    }
+
+                    String specarg = spec.substring(sidx);
+                    switch (specop) {
+                        case '.':  // terminate the option sequence
+                            resultString = (specarg.length() != 0) ? specarg.intern() : opt;
+                            break doArgs;
+                        case '?':  // abort the option sequence
+                            resultString = (specarg.length() != 0) ? specarg.intern() : arg;
+                            isError = true;
+                            break eachSpec;
+                        case '@':  // change the effective opt name
+                            opt = specarg.intern();
+                            break;
+                        case '>':  // shift remaining arg val to next arg
+                            pbp.add(specarg + val);  // push a new argument
+                            val = "";
+                            break;
+                        case '!':  // negation option
+                            String negopt = (specarg.length() != 0) ? specarg.intern() : opt;
+                            properties.remove(negopt);
+                            properties.put(negopt, null);  // leave placeholder
+                            didAction = true;
+                            break;
+                        case '$':  // normal "boolean" option
+                            String boolval;
+                            if (specarg.length() != 0) {
+                                // If there is a given spec token, store it.
+                                boolval = specarg;
+                            } else {
+                                String old = properties.get(opt);
+                                if (old == null || old.length() == 0) {
+                                    boolval = "1";
+                                } else {
+                                    // Increment any previous value as a numeral.
+                                    boolval = "" + (1 + Integer.parseInt(old));
+                                }
+                            }
+                            properties.put(opt, boolval);
+                            didAction = true;
+                            break;
+                        case '=':  // "string" option
+                        case '&':  // "collection" option
+                            // Read an option.
+                            boolean append = (specop == '&');
+                            String strval;
+                            if (pbp.hasPrevious()) {
+                                strval = pbp.previous();
+                                pbp.remove();
+                            } else if (argp.hasNext()) {
+                                strval = argp.next();
+                            } else {
+                                resultString = arg + " ?";
+                                isError = true;
+                                break eachSpec;
+                            }
+                            if (append) {
+                                String old = properties.get(opt);
+                                if (old != null) {
+                                    // Append new val to old with embedded delim.
+                                    String delim = specarg;
+                                    if (delim.length() == 0) {
+                                        delim = " ";
+                                    }
+                                    strval = old + specarg + strval;
+                                }
+                            }
+                            properties.put(opt, strval);
+                            didAction = true;
+                            break;
+                        default:
+                            throw new RuntimeException("bad spec for "
+                                    + opt + ": " + spec);
+                    }
+                }
+
+                // Done processing specs.
+                if (didAction && !isError) {
+                    continue doArgs;
+                }
+
+                // The specs should have done something, but did not.
+                while (pbp.nextIndex() > pbpMark) {
+                    // Remove anything pushed during these specs.
+                    pbp.previous();
+                    pbp.remove();
+                }
+
+                if (isError) {
+                    throw new IllegalArgumentException(resultString);
+                }
+
+                if (optlen == 0) {
+                    // We cannot try a shorter matching option.
+                    break tryOpt;
+                }
+            }
+
+            // If we come here, there was no matching option.
+            // So, push back the argument, and return to caller.
+            pbp.add(arg);
+            break doArgs;
+        }
+        // Report number of arguments consumed.
+        args.subList(0, argp.nextIndex()).clear();
+        // Report any unconsumed partial argument.
+        while (pbp.hasPrevious()) {
+            args.add(0, pbp.previous());
+        }
+        //System.out.println(args+" // "+properties+" -> "+resultString);
+        return resultString;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/InstructionAssembler.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+
+import xmlkit.XMLKit.Element;
+import java.util.HashMap;
+/*
+ * @author jrose
+ */
+abstract class InstructionAssembler extends InstructionSyntax {
+
+    InstructionAssembler() {
+    }
+
+    public static String assemble(Element instructions, String pcAttrName,
+            ClassSyntax.GetCPIndex getCPI) {
+        int insCount = instructions.size();
+        Element[] insElems = new Element[insCount];
+        int[] elemToIndexMap;
+        int[] insLocs;
+        byte[] ops = new byte[insCount];
+        int[] operands = new int[insCount];
+        boolean[] isWide = new boolean[insCount];
+        int[] branches;
+        int[] branchInsLocs;
+        HashMap<String, String> labels = new HashMap<String, String>();
+
+        final int WIDE = 0xc4;
+        final int GOTO = 0xa7;
+        final int GOTO_W = 0xc8;
+        final int GOTO_LEN = 3;
+        final int GOTO_W_LEN = 5;
+        assert ("wide".equals(bcNames[WIDE]));
+        assert ("goto".equals(bcNames[GOTO]));
+        assert ("goto_w".equals(bcNames[GOTO_W]));
+        assert (bcFormats[GOTO].length() == GOTO_LEN);
+        assert (bcFormats[GOTO_W].length() == GOTO_W_LEN);
+
+        // Unpack instructions into temp. arrays, and find branches and labels.
+        {
+            elemToIndexMap = (pcAttrName != null) ? new int[insCount] : null;
+            int[] buffer = operands;
+            int id = 0;
+            int branchCount = 0;
+            for (int i = 0; i < insCount; i++) {
+                Element ins = (Element) instructions.get(i);
+                if (elemToIndexMap != null) {
+                    elemToIndexMap[i] = (ins.getAttr(pcAttrName) != null ? id : -1);
+                }
+                String lab = ins.getAttr("pc");
+                if (lab != null) {
+                    labels.put(lab, String.valueOf(id));
+                }
+                int op = opCode(ins.getName());
+                if (op < 0) {
+                    assert (ins.getAttr(pcAttrName) != null
+                            || ins.getName().equals("label"));
+                    continue;  // delete PC holder element
+                }
+                if (op == WIDE) { //0xc4
+                    isWide[id] = true;  // force wide format
+                    continue;
+                }
+                if (bcFormats[op].indexOf('o') >= 0) {
+                    buffer[branchCount++] = id;
+                }
+                if (bcFormats[op] == bcWideFormats[op]) {
+                    isWide[id] = false;
+                }
+                insElems[id] = ins;
+                ops[id] = (byte) op;
+                id++;
+            }
+            insCount = id;  // maybe we deleted some wide prefixes, etc.
+            branches = new int[branchCount + 1];
+            System.arraycopy(buffer, 0, branches, 0, branchCount);
+            branches[branchCount] = -1;  // sentinel
+        }
+
+        // Compute instruction sizes.  These sizes are final,
+        // except for branch instructions, which may need lengthening.
+        // Some instructions (ldc, bipush, iload, iinc) are automagically widened.
+        insLocs = new int[insCount + 1];
+        int loc = 0;
+        for (int bn = 0, id = 0; id < insCount; id++) {
+            insLocs[id] = loc;
+            Element ins = insElems[id];
+            int op = ops[id] & 0xFF;
+            String format = opFormat(op, isWide[id]);
+            // Make sure operands fit within the given format.
+            for (int j = 1, jlimit = format.length(); j < jlimit; j++) {
+                char fc = format.charAt(j);
+                int x = 0;
+                switch (fc) {
+                    case 'l':
+                        x = (int) ins.getAttrLong("loc");
+                        assert (x >= 0);
+                        if (x > 0xFF && !isWide[id]) {
+                            isWide[id] = true;
+                            format = opFormat(op, isWide[id]);
+                        }
+                        assert (x <= 0xFFFF);
+                        break;
+                    case 'k':
+                        char fc2 = format.charAt(Math.min(j + 1, format.length() - 1));
+                        x = getCPIndex(ins, fc2, getCPI);
+                        if (x > 0xFF && j == jlimit - 1) {
+                            assert (op == 0x12); //ldc
+                            ops[id] = (byte) (op = 0x13); //ldc_w
+                            format = opFormat(op);
+                        }
+                        assert (x <= 0xFFFF);
+                        j++;  // skip type-of-constant marker
+                        break;
+                    case 'x':
+                        x = (int) ins.getAttrLong("num");
+                        assert (x >= 0 && x <= ((j == jlimit - 1) ? 0xFF : 0xFFFF));
+                        break;
+                    case 's':
+                        x = (int) ins.getAttrLong("num");
+                        if (x != (byte) x && j == jlimit - 1) {
+                            switch (op) {
+                                case 0x10: //bipush
+                                    ops[id] = (byte) (op = 0x11); //sipush
+                                    break;
+                                case 0x84: //iinc
+                                    isWide[id] = true;
+                                    format = opFormat(op, isWide[id]);
+                                    break;
+                                default:
+                                    assert (false);  // cannot lengthen
+                            }
+                        }
+                        // unsign the value now, to make later steps clearer
+                        if (j == jlimit - 1) {
+                            assert (x == (byte) x);
+                            x = x & 0xFF;
+                        } else {
+                            assert (x == (short) x);
+                            x = x & 0xFFFF;
+                        }
+                        break;
+                    case 'o':
+                        assert (branches[bn] == id);
+                        bn++;
+                        // make local copies of the branches, and fix up labels
+                        insElems[id] = ins = new Element(ins);
+                        String newLab = labels.get(ins.getAttr("lab"));
+                        assert (newLab != null);
+                        ins.setAttr("lab", newLab);
+                        int prevCas = 0;
+                        int k = 0;
+                        for (Element cas : ins.elements()) {
+                            assert (cas.getName().equals("Case"));
+                            ins.set(k++, cas = new Element(cas));
+                            newLab = labels.get(cas.getAttr("lab"));
+                            assert (newLab != null);
+                            cas.setAttr("lab", newLab);
+                            int thisCas = (int) cas.getAttrLong("num");
+                            assert (op == 0xab
+                                    || op == 0xaa && (k == 0 || thisCas == prevCas + 1));
+                            prevCas = thisCas;
+                        }
+                        break;
+                    case 't':
+                        // switch table is represented as Switch.Case sub-elements
+                        break;
+                    default:
+                        assert (false);
+                }
+                operands[id] = x;  // record operand (last if there are 2)
+                // skip redundant chars
+                while (j + 1 < jlimit && format.charAt(j + 1) == fc) {
+                    ++j;
+                }
+            }
+
+            switch (op) {
+                case 0xaa: //tableswitch
+                    loc = switchBase(loc);
+                    loc += 4 * (3 + ins.size());
+                    break;
+                case 0xab: //lookupswitch
+                    loc = switchBase(loc);
+                    loc += 4 * (2 + 2 * ins.size());
+                    break;
+                default:
+                    if (isWide[id]) {
+                        loc++;  // 'wide' opcode prefix
+                    }
+                    loc += format.length();
+                    break;
+            }
+        }
+        insLocs[insCount] = loc;
+
+        // compute branch offsets, and see if any branches need expansion
+        for (int maxTries = 9, tries = 0;; ++tries) {
+            boolean overflowing = false;
+            boolean[] branchExpansions = null;
+            for (int bn = 0; bn < branches.length - 1; bn++) {
+                int id = branches[bn];
+                Element ins = insElems[id];
+                int insSize = insLocs[id + 1] - insLocs[id];
+                int origin = insLocs[id];
+                int target = insLocs[(int) ins.getAttrLong("lab")];
+                int offset = target - origin;
+                operands[id] = offset;
+                //System.out.println("branch id="+id+" len="+insSize+" to="+target+" offset="+offset);
+                assert (insSize == GOTO_LEN || insSize == GOTO_W_LEN || ins.getName().indexOf("switch") > 0);
+                boolean thisOverflow = (insSize == GOTO_LEN && (offset != (short) offset));
+                if (thisOverflow && !overflowing) {
+                    overflowing = true;
+                    branchExpansions = new boolean[branches.length];
+                }
+                if (thisOverflow || tries == maxTries - 1) {
+                    // lengthen the branch
+                    assert (!(thisOverflow && isWide[id]));
+                    isWide[id] = true;
+                    branchExpansions[bn] = true;
+                }
+            }
+            if (!overflowing) {
+                break;  // done, usually on first try
+            }
+            assert (tries <= maxTries);
+
+            // Walk over all instructions, expanding branches and updating locations.
+            int fixup = 0;
+            for (int bn = 0, id = 0; id < insCount; id++) {
+                insLocs[id] += fixup;
+                if (branches[bn] == id) {
+                    int op = ops[id] & 0xFF;
+                    int wop;
+                    boolean invert;
+                    if (branchExpansions[bn]) {
+                        switch (op) {
+                            case GOTO: //0xa7
+                                wop = GOTO_W; //0xc8
+                                invert = false;
+                                break;
+                            case 0xa8: //jsr
+                                wop = 0xc9; //jsr_w
+                                invert = false;
+                                break;
+                            default:
+                                wop = invertBranchOp(op);
+                                invert = true;
+                                break;
+                        }
+                        assert (op != wop);
+                        ops[id] = (byte) wop;
+                        isWide[id] = invert;
+                        if (invert) {
+                            fixup += GOTO_W_LEN;  //branch around a wide goto
+                        } else {
+                            fixup += (GOTO_W_LEN - GOTO_LEN);
+                        }
+                        // done expanding:  ops and isWide reflect the decision
+                    }
+                    bn++;
+                }
+            }
+            insLocs[insCount] += fixup;
+        }
+        // we know the layout now
+
+        // notify the caller of offsets, if requested
+        if (elemToIndexMap != null) {
+            for (int i = 0; i < elemToIndexMap.length; i++) {
+                int id = elemToIndexMap[i];
+                if (id >= 0) {
+                    Element ins = (Element) instructions.get(i);
+                    ins.setAttr(pcAttrName, "" + insLocs[id]);
+                }
+            }
+            elemToIndexMap = null;  // release the pointer
+        }
+
+        // output the bytes
+        StringBuffer sbuf = new StringBuffer(insLocs[insCount]);
+        for (int bn = 0, id = 0; id < insCount; id++) {
+            //System.out.println("output id="+id+" loc="+insLocs[id]+" len="+(insLocs[id+1]-insLocs[id])+" #sbuf="+sbuf.length());
+            assert (sbuf.length() == insLocs[id]);
+            Element ins;
+            int pc = insLocs[id];
+            int nextpc = insLocs[id + 1];
+            int op = ops[id] & 0xFF;
+            int opnd = operands[id];
+            String format;
+            if (branches[bn] == id) {
+                bn++;
+                sbuf.append((char) op);
+                if (isWide[id]) {
+                    // emit <ifop lab=1f> <goto_w target> <label pc=1f>
+                    int target = pc + opnd;
+                    putInt(sbuf, nextpc - pc, -2);
+                    assert (sbuf.length() == pc + GOTO_LEN);
+                    sbuf.append((char) GOTO_W);
+                    putInt(sbuf, target - (pc + GOTO_LEN), 4);
+                } else if (op == 0xaa || //tableswitch
+                        op == 0xab) {  //lookupswitch
+                    ins = insElems[id];
+                    for (int pad = switchBase(pc) - (pc + 1); pad > 0; pad--) {
+                        sbuf.append((char) 0);
+                    }
+                    assert (pc + opnd == insLocs[(int) ins.getAttrLong("lab")]);
+                    putInt(sbuf, opnd, 4); // default label
+                    if (op == 0xaa) {  //tableswitch
+                        Element cas0 = (Element) ins.get(0);
+                        int lowCase = (int) cas0.getAttrLong("num");
+                        Element casN = (Element) ins.get(ins.size() - 1);
+                        int highCase = (int) casN.getAttrLong("num");
+                        assert (highCase - lowCase + 1 == ins.size());
+                        putInt(sbuf, lowCase, 4);
+                        putInt(sbuf, highCase, 4);
+                        int caseForAssert = lowCase;
+                        for (Element cas : ins.elements()) {
+                            int target = insLocs[(int) cas.getAttrLong("lab")];
+                            assert (cas.getAttrLong("num") == caseForAssert++);
+                            putInt(sbuf, target - pc, 4);
+                        }
+                    } else {  //lookupswitch
+                        int caseCount = ins.size();
+                        putInt(sbuf, caseCount, 4);
+                        for (Element cas : ins.elements()) {
+                            int target = insLocs[(int) cas.getAttrLong("lab")];
+                            putInt(sbuf, (int) cas.getAttrLong("num"), 4);
+                            putInt(sbuf, target - pc, 4);
+                        }
+                    }
+                    assert (nextpc == sbuf.length());
+                } else {
+                    putInt(sbuf, opnd, -(nextpc - (pc + 1)));
+                }
+            } else if (nextpc == pc + 1) {
+                // a single-byte instruction
+                sbuf.append((char) op);
+            } else {
+                // picky stuff
+                boolean wide = isWide[id];
+                if (wide) {
+                    sbuf.append((char) WIDE);
+                    pc++;
+                }
+                sbuf.append((char) op);
+                int opnd1;
+                int opnd2 = opnd;
+                switch (op) {
+                    case 0x84:  //iinc
+                        ins = insElems[id];
+                        opnd1 = (int) ins.getAttrLong("loc");
+                        if (isWide[id]) {
+                            putInt(sbuf, opnd1, 2);
+                            putInt(sbuf, opnd2, 2);
+                        } else {
+                            putInt(sbuf, opnd1, 1);
+                            putInt(sbuf, opnd2, 1);
+                        }
+                        break;
+                    case 0xc5: //multianewarray
+                        ins = insElems[id];
+                        opnd1 = getCPIndex(ins, 'c', getCPI);
+                        putInt(sbuf, opnd1, 2);
+                        putInt(sbuf, opnd2, 1);
+                        break;
+                    case 0xb9: //invokeinterface
+                        ins = insElems[id];
+                        opnd1 = getCPIndex(ins, 'n', getCPI);
+                        putInt(sbuf, opnd1, 2);
+                        opnd2 = (int) ins.getAttrLong("num");
+                        if (opnd2 == 0) {
+                            opnd2 = ClassSyntax.computeInterfaceNum(ins.getAttr("val"));
+                        }
+                        putInt(sbuf, opnd2, 2);
+                        break;
+                    default:
+                        // put the single operand and be done
+                        putInt(sbuf, opnd, nextpc - (pc + 1));
+                        break;
+                }
+            }
+        }
+        assert (sbuf.length() == insLocs[insCount]);
+
+        return sbuf.toString();
+    }
+
+    static int getCPIndex(Element ins, char ctype,
+            ClassSyntax.GetCPIndex getCPI) {
+        int x = (int) ins.getAttrLong("ref");
+        if (x == 0 && getCPI != null) {
+            String val = ins.getAttr("val");
+            if (val == null || val.equals("")) {
+                val = ins.getText().toString();
+            }
+            byte tag;
+            switch (ctype) {
+                case 'k':
+                    tag = (byte) ins.getAttrLong("tag");
+                    break;
+                case 'c':
+                    tag = ClassSyntax.CONSTANT_Class;
+                    break;
+                case 'f':
+                    tag = ClassSyntax.CONSTANT_Fieldref;
+                    break;
+                case 'm':
+                    tag = ClassSyntax.CONSTANT_Methodref;
+                    break;
+                case 'n':
+                    tag = ClassSyntax.CONSTANT_InterfaceMethodref;
+                    break;
+                default:
+                    throw new Error("bad ctype " + ctype + " in " + ins);
+            }
+            x = getCPI.getCPIndex(tag, val);
+            //System.out.println("getCPIndex "+ins+" => "+tag+"/"+val+" => "+x);
+        } else {
+            assert (x > 0);
+        }
+        return x;
+    }
+
+    static void putInt(StringBuffer sbuf, int x, int len) {
+        //System.out.println("putInt x="+x+" len="+len);
+        boolean isSigned = false;
+        if (len < 0) {
+            len = -len;
+            isSigned = true;
+        }
+        assert (len == 1 || len == 2 || len == 4);
+        int insig = ((4 - len) * 8);  // how many insignificant bits?
+        int sx = x << insig;
+        ;
+        assert (x == (isSigned ? (sx >> insig) : (sx >>> insig)));
+        for (int i = 0; i < len; i++) {
+            sbuf.append((char) (sx >>> 24));
+            sx <<= 8;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/InstructionSyntax.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+
+import xmlkit.XMLKit.Element;
+import java.util.HashMap;
+import java.util.Map;
+/*
+ * @author jrose
+ */
+public abstract class InstructionSyntax {
+
+    InstructionSyntax() {
+    }
+    static final String[] bcNames;
+    static final String[] bcFormats;
+    static final String[] bcWideFormats;
+    static final HashMap<String, Integer> bcCodes;
+    static final HashMap<String, Element> abbrevs;
+    static final HashMap<Element, String> rabbrevs;
+
+    static {
+        TokenList tl = new TokenList(
+                " nop aconst_null iconst_m1 iconst_0 iconst_1 iconst_2 iconst_3"
+                + " iconst_4 iconst_5 lconst_0 lconst_1 fconst_0 fconst_1 fconst_2"
+                + " dconst_0 dconst_1 bipush/s sipush/ss ldc/k ldc_w/kk ldc2_w/kk"
+                + " iload/wl lload/wl fload/wl dload/wl aload/wl iload_0 iload_1"
+                + " iload_2 iload_3 lload_0 lload_1 lload_2 lload_3 fload_0 fload_1"
+                + " fload_2 fload_3 dload_0 dload_1 dload_2 dload_3 aload_0 aload_1"
+                + " aload_2 aload_3 iaload laload faload daload aaload baload caload"
+                + " saload istore/wl lstore/wl fstore/wl dstore/wl astore/wl"
+                + " istore_0 istore_1 istore_2 istore_3 lstore_0 lstore_1 lstore_2"
+                + " lstore_3 fstore_0 fstore_1 fstore_2 fstore_3 dstore_0 dstore_1"
+                + " dstore_2 dstore_3 astore_0 astore_1 astore_2 astore_3 iastore"
+                + " lastore fastore dastore aastore bastore castore sastore pop pop2"
+                + " dup dup_x1 dup_x2 dup2 dup2_x1 dup2_x2 swap iadd ladd fadd dadd"
+                + " isub lsub fsub dsub imul lmul fmul dmul idiv ldiv fdiv ddiv irem"
+                + " lrem frem drem ineg lneg fneg dneg ishl lshl ishr lshr iushr"
+                + " lushr iand land ior lor ixor lxor iinc/wls i2l i2f i2d l2i l2f"
+                + " l2d f2i f2l f2d d2i d2l d2f i2b i2c i2s lcmp fcmpl fcmpg dcmpl"
+                + " dcmpg ifeq/oo ifne/oo iflt/oo ifge/oo ifgt/oo ifle/oo"
+                + " if_icmpeq/oo if_icmpne/oo if_icmplt/oo if_icmpge/oo if_icmpgt/oo"
+                + " if_icmple/oo if_acmpeq/oo if_acmpne/oo goto/oo jsr/oo ret/wl"
+                + " tableswitch/oooot lookupswitch/oooot ireturn lreturn freturn dreturn areturn"
+                + " return getstatic/kf putstatic/kf getfield/kf putfield/kf"
+                + " invokevirtual/km invokespecial/km invokestatic/km"
+                + " invokeinterface/knxx xxxunusedxxx new/kc newarray/x anewarray/kc"
+                + " arraylength athrow checkcast/kc instanceof/kc monitorenter"
+                + " monitorexit wide multianewarray/kcx ifnull/oo ifnonnull/oo"
+                + " goto_w/oooo jsr_w/oooo");
+        assert (tl.size() == 202);  // this many instructions!
+        HashMap<String, Integer> map = new HashMap<String, Integer>(tl.size());
+        String[] names = tl.toArray(new String[tl.size()]);
+        String[] formats = new String[names.length];
+        String[] wideFormats = new String[names.length];
+        StringBuilder sbuf = new StringBuilder();
+        sbuf.append('i');  // all op formats begin with "i"
+        int i = 0;
+        for (String ins : names) {
+            assert (ins == ins.trim());  // no whitespace
+            int sfx = ins.indexOf('/');
+            String format = "i";
+            String wideFormat = null;
+            if (sfx >= 0) {
+                format = ins.substring(sfx + 1);
+                ins = ins.substring(0, sfx);
+                if (format.charAt(0) == 'w') {
+                    format = format.substring(1);
+                    sbuf.setLength(1);
+                    for (int j = 0; j < format.length(); j++) {
+                        // double everything except the initial 'i'
+                        sbuf.append(format.charAt(j));
+                        sbuf.append(format.charAt(j));
+                    }
+                    wideFormat = sbuf.toString().intern();
+                }
+                sbuf.setLength(1);
+                sbuf.append(format);
+                format = sbuf.toString().intern();
+            }
+            ins = ins.intern();
+            names[i] = ins;
+            formats[i] = format;
+            wideFormats[i] = (wideFormat != null) ? wideFormat : format;
+            //System.out.println(ins+" "+format+" "+wideFormat);
+            map.put(ins, i++);
+        }
+        //map = Collections.unmodifiableMap(map);
+
+        HashMap<String, Element> abb = new HashMap<String, Element>(tl.size() / 2);
+        abb.put("iconst_m1", new Element("bipush", "num", "-1"));
+        for (String ins : names) {
+            int sfx = ins.indexOf('_');
+            if (sfx >= 0 && Character.isDigit(ins.charAt(sfx + 1))) {
+                String pfx = ins.substring(0, sfx).intern();
+                String num = ins.substring(sfx + 1);
+                String att = pfx.endsWith("const") ? "num" : "loc";
+                Element exp = new Element(pfx, att, num).deepFreeze();
+                abb.put(ins, exp);
+            }
+        }
+        //abb = Collections.unmodifiableMap(abb);
+        HashMap<Element, String> rabb = new HashMap<Element, String>(tl.size() / 2);
+        for (Map.Entry<String, Element> e : abb.entrySet()) {
+            rabb.put(e.getValue(), e.getKey());
+        }
+        //rabb = Collections.unmodifiableMap(rabb);
+
+
+        bcNames = names;
+        bcFormats = formats;
+        bcWideFormats = wideFormats;
+        bcCodes = map;
+        abbrevs = abb;
+        rabbrevs = rabb;
+    }
+
+    public static String opName(int op) {
+        if (op >= 0 && op < bcNames.length) {
+            return bcNames[op];
+        }
+        return "unknown#" + op;
+    }
+
+    public static String opFormat(int op) {
+        return opFormat(op, false);
+    }
+
+    public static String opFormat(int op, boolean isWide) {
+        if (op >= 0 && op < bcFormats.length) {
+            return (isWide ? bcWideFormats[op] : bcFormats[op]);
+        }
+        return "?";
+    }
+
+    public static int opCode(String opName) {
+        Integer op = (Integer) bcCodes.get(opName);
+        if (op != null) {
+            return op.intValue();
+        }
+        return -1;
+    }
+
+    public static Element expandAbbrev(String opName) {
+        return abbrevs.get(opName);
+    }
+
+    public static String findAbbrev(Element op) {
+        return rabbrevs.get(op);
+    }
+
+    public static int invertBranchOp(int op) {
+        assert (opFormat(op).indexOf('o') >= 0);
+        final int IFMIN = 0x99;
+        final int IFMAX = 0xa6;
+        final int IFMIN2 = 0xc6;
+        final int IFMAX2 = 0xc7;
+        assert (bcNames[IFMIN] == "ifeq");
+        assert (bcNames[IFMAX] == "if_acmpne");
+        assert (bcNames[IFMIN2] == "ifnonnull");
+        assert (bcNames[IFMAX2] == "ifnull");
+        int rop;
+        if (op >= IFMIN && op <= IFMAX) {
+            rop = IFMIN + ((op - IFMIN) ^ 1);
+        } else if (op >= IFMIN2 && op <= IFMAX2) {
+            rop = IFMIN2 + ((op - IFMIN2) ^ 1);
+        } else {
+            assert (false);
+            rop = op;
+        }
+        assert (opFormat(rop).indexOf('o') >= 0);
+        return rop;
+    }
+
+    public static Element parse(String bytes) {
+        Element e = new Element("Instructions", bytes.length());
+        boolean willBeWide;
+        boolean isWide = false;
+        Element[] tempMap = new Element[bytes.length()];
+        for (int pc = 0, nextpc; pc < bytes.length(); pc = nextpc) {
+            int op = bytes.charAt(pc);
+            Element i = new Element(opName(op));
+
+            nextpc = pc + 1;
+            int locarg = 0;
+            int cparg = 0;
+            int intarg = 0;
+            int labelarg = 0;
+
+            willBeWide = false;
+            switch (op) {
+                case 0xc4: //wide
+                    willBeWide = true;
+                    break;
+                case 0x10: //bipush
+                    intarg = nextpc++;
+                    intarg *= -1;  //mark signed
+                    break;
+                case 0x11: //sipush
+                    intarg = nextpc;
+                    nextpc += 2;
+                    intarg *= -1;  //mark signed
+                    break;
+                case 0x12: //ldc
+                    cparg = nextpc++;
+                    break;
+                case 0x13: //ldc_w
+                case 0x14: //ldc2_w
+                case 0xb2: //getstatic
+                case 0xb3: //putstatic
+                case 0xb4: //getfield
+                case 0xb5: //putfield
+                case 0xb6: //invokevirtual
+                case 0xb7: //invokespecial
+                case 0xb8: //invokestatic
+                case 0xbb: //new
+                case 0xbd: //anewarray
+                case 0xc0: //checkcast
+                case 0xc1: //instanceof
+                    cparg = nextpc;
+                    nextpc += 2;
+                    break;
+                case 0xb9: //invokeinterface
+                    cparg = nextpc;
+                    nextpc += 2;
+                    intarg = nextpc;
+                    nextpc += 2;
+                    break;
+                case 0xc5: //multianewarray
+                    cparg = nextpc;
+                    nextpc += 2;
+                    intarg = nextpc++;
+                    break;
+                case 0x15: //iload
+                case 0x16: //lload
+                case 0x17: //fload
+                case 0x18: //dload
+                case 0x19: //aload
+                case 0x36: //istore
+                case 0x37: //lstore
+                case 0x38: //fstore
+                case 0x39: //dstore
+                case 0x3a: //astore
+                case 0xa9: //ret
+                    locarg = nextpc++;
+                    if (isWide) {
+                        nextpc++;
+                    }
+                    break;
+                case 0x84: //iinc
+                    locarg = nextpc++;
+                    if (isWide) {
+                        nextpc++;
+                    }
+                    intarg = nextpc++;
+                    if (isWide) {
+                        nextpc++;
+                    }
+                    intarg *= -1;  //mark signed
+                    break;
+                case 0x99: //ifeq
+                case 0x9a: //ifne
+                case 0x9b: //iflt
+                case 0x9c: //ifge
+                case 0x9d: //ifgt
+                case 0x9e: //ifle
+                case 0x9f: //if_icmpeq
+                case 0xa0: //if_icmpne
+                case 0xa1: //if_icmplt
+                case 0xa2: //if_icmpge
+                case 0xa3: //if_icmpgt
+                case 0xa4: //if_icmple
+                case 0xa5: //if_acmpeq
+                case 0xa6: //if_acmpne
+                case 0xa7: //goto
+                case 0xa8: //jsr
+                    labelarg = nextpc;
+                    nextpc += 2;
+                    break;
+                case 0xbc: //newarray
+                    intarg = nextpc++;
+                    break;
+                case 0xc6: //ifnull
+                case 0xc7: //ifnonnull
+                    labelarg = nextpc;
+                    nextpc += 2;
+                    break;
+                case 0xc8: //goto_w
+                case 0xc9: //jsr_w
+                    labelarg = nextpc;
+                    nextpc += 4;
+                    break;
+
+                // save the best for last:
+                case 0xaa: //tableswitch
+                    nextpc = parseSwitch(bytes, pc, true, i);
+                    break;
+                case 0xab: //lookupswitch
+                    nextpc = parseSwitch(bytes, pc, false, i);
+                    break;
+            }
+
+            String format = null;
+            assert ((format = opFormat(op, isWide)) != null);
+            //System.out.println("pc="+pc+" len="+(nextpc - pc)+" w="+isWide+" op="+op+" name="+opName(op)+" format="+format);
+            assert ((nextpc - pc) == format.length() || format.indexOf('t') >= 0);
+
+            // Parse out instruction fields.
+            if (locarg != 0) {
+                int len = nextpc - locarg;
+                if (intarg != 0) {
+                    len /= 2;  // split
+                }
+                i.setAttr("loc", "" + getInt(bytes, locarg, len));
+                assert ('l' == format.charAt(locarg - pc + 0));
+                assert ('l' == format.charAt(locarg - pc + len - 1));
+            }
+            if (cparg != 0) {
+                int len = nextpc - cparg;
+                if (len > 2) {
+                    len = 2;
+                }
+                i.setAttr("ref", "" + getInt(bytes, cparg, len));
+                assert ('k' == format.charAt(cparg - pc + 0));
+            }
+            if (intarg != 0) {
+                boolean isSigned = (intarg < 0);
+                if (isSigned) {
+                    intarg *= -1;
+                }
+                int len = nextpc - intarg;
+                i.setAttr("num", "" + getInt(bytes, intarg, isSigned ? -len : len));
+                assert ((isSigned ? 's' : 'x') == format.charAt(intarg - pc + 0));
+                assert ((isSigned ? 's' : 'x') == format.charAt(intarg - pc + len - 1));
+            }
+            if (labelarg != 0) {
+                int len = nextpc - labelarg;
+                int offset = getInt(bytes, labelarg, -len);
+                int target = pc + offset;
+                i.setAttr("lab", "" + target);
+                assert ('o' == format.charAt(labelarg - pc + 0));
+                assert ('o' == format.charAt(labelarg - pc + len - 1));
+            }
+
+            e.add(i);
+            tempMap[pc] = i;
+            isWide = willBeWide;
+        }
+
+        // Mark targets of branches.
+        for (Element i : e.elements()) {
+            for (int j = -1; j < i.size(); j++) {
+                Element c = (j < 0) ? i : (Element) i.get(j);
+                Number targetNum = c.getAttrNumber("lab");
+                if (targetNum != null) {
+                    int target = targetNum.intValue();
+                    Element ti = null;
+                    if (target >= 0 && target < tempMap.length) {
+                        ti = tempMap[target];
+                    }
+                    if (ti != null) {
+                        ti.setAttr("pc", "" + target);
+                    } else {
+                        c.setAttr("lab.error", "");
+                    }
+                }
+            }
+        }
+
+        // Shrink to fit:
+        for (Element i : e.elements()) {
+            i.trimToSize();
+        }
+        e.trimToSize();
+
+        /*
+        String assem = assemble(e);
+        if (!assem.equals(bytes)) {
+        System.out.println("Bytes: "+bytes);
+        System.out.println("Insns: "+e);
+        System.out.println("Assem: "+parse(assem));
+        }
+         */
+
+        return e;
+    }
+
+    static int switchBase(int pc) {
+        int apc = pc + 1;
+        apc += (-apc) & 3;
+        return apc;
+    }
+
+    static int parseSwitch(String s, int pc, boolean isTable, Element i) {
+        int apc = switchBase(pc);
+        int defLabel = pc + getInt(s, apc + 4 * 0, 4);
+        i.setAttr("lab", "" + defLabel);
+        if (isTable) {
+            int lowCase = getInt(s, apc + 4 * 1, 4);
+            int highCase = getInt(s, apc + 4 * 2, 4);
+            int caseCount = highCase - lowCase + 1;
+            for (int n = 0; n < caseCount; n++) {
+                Element c = new Element("Case", 4);
+                int caseVal = lowCase + n;
+                int caseLab = getInt(s, apc + 4 * (3 + n), 4) + pc;
+                c.setAttr("num", "" + caseVal);
+                c.setAttr("lab", "" + caseLab);
+                assert (c.getExtraCapacity() == 0);
+                i.add(c);
+            }
+            return apc + 4 * (3 + caseCount);
+        } else {
+            int caseCount = getInt(s, apc + 4 * 1, 4);
+            for (int n = 0; n < caseCount; n++) {
+                Element c = new Element("Case", 4);
+                int caseVal = getInt(s, apc + 4 * (2 + (2 * n) + 0), 4);
+                int caseLab = getInt(s, apc + 4 * (2 + (2 * n) + 1), 4) + pc;
+                c.setAttr("num", "" + caseVal);
+                c.setAttr("lab", "" + caseLab);
+                assert (c.getExtraCapacity() == 0);
+                i.add(c);
+            }
+            return apc + 4 * (2 + 2 * caseCount);
+        }
+    }
+
+    static int getInt(String s, int pc, int len) {
+        //System.out.println("getInt s["+s.length()+"] pc="+pc+" len="+len);
+        int result = s.charAt(pc);
+        if (len < 0) {
+            len = -len;
+            result = (byte) result;
+        }
+        if (!(len == 1 || len == 2 || len == 4)) {
+            System.out.println("len=" + len);
+        }
+        assert (len == 1 || len == 2 || len == 4);
+        for (int i = 1; i < len; i++) {
+            result <<= 8;
+            result += s.charAt(pc + i) & 0xFF;
+        }
+        return result;
+    }
+
+    public static String assemble(Element instructions) {
+        return InstructionAssembler.assemble(instructions, null, null);
+    }
+
+    public static String assemble(Element instructions, String pcAttrName) {
+        return InstructionAssembler.assemble(instructions, pcAttrName, null);
+    }
+
+    public static String assemble(Element instructions, ClassSyntax.GetCPIndex getCPI) {
+        return InstructionAssembler.assemble(instructions, null, getCPI);
+    }
+
+    public static String assemble(Element instructions, String pcAttrName,
+            ClassSyntax.GetCPIndex getCPI) {
+        return InstructionAssembler.assemble(instructions, pcAttrName, getCPI);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/TokenList.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+
+import java.util.*;
+
+/**
+ * A List of Strings each representing a word or token.
+ * This object itself is a CharSequence whose characters consist
+ * of all the tokens, separated by blanks.
+ *
+ * @author jrose
+ */
+public class TokenList extends ArrayList<String> implements CharSequence {
+
+    protected String separator;
+    protected boolean frozen;
+
+    public TokenList() {
+        this.separator = " ";
+    }
+
+    public TokenList(Collection<? extends Object> tokens) {
+        super(tokens.size());
+        this.separator = " ";
+        addTokens(tokens);
+    }
+
+    public TokenList(Collection<? extends Object> tokens, String separator) {
+        super(tokens.size());
+        this.separator = separator;
+        addTokens(tokens);
+    }
+
+    public TokenList(Object[] tokens) {
+        super(tokens.length);
+        this.separator = " ";
+        addTokens(tokens, 0, tokens.length);
+    }
+
+    public TokenList(Object[] tokens, int beg, int end) {
+        super(end - beg);  // capacity
+        this.separator = " ";
+        addTokens(tokens, beg, end);
+    }
+
+    public TokenList(Object[] tokens, int beg, int end, String separator) {
+        super(end - beg);  // capacity
+        this.separator = separator;
+        addTokens(tokens, beg, end);
+    }
+
+    public TokenList(String tokenStr) {
+        this(tokenStr, " ", false);
+    }
+
+    public TokenList(String tokenStr, String separator) {
+        this(tokenStr, separator, true);
+    }
+
+    public TokenList(String tokenStr, String separator, boolean allowNulls) {
+        super(tokenStr.length() / 5);
+        this.separator = separator;
+        addTokens(tokenStr, allowNulls);
+    }
+    static public final TokenList EMPTY;
+
+    static {
+        TokenList tl = new TokenList(new Object[0]);
+        tl.freeze();
+        EMPTY = tl;
+    }
+
+    public void freeze() {
+        if (!frozen) {
+            for (ListIterator<String> i = listIterator(); i.hasNext();) {
+                i.set(i.next().toString());
+            }
+            trimToSize();
+            frozen = true;
+        }
+    }
+
+    public boolean isFrozen() {
+        return frozen;
+    }
+
+    void checkNotFrozen() {
+        if (isFrozen()) {
+            throw new UnsupportedOperationException("cannot modify frozen TokenList");
+        }
+    }
+
+    public String getSeparator() {
+        return separator;
+    }
+
+    public void setSeparator(String separator) {
+        checkNotFrozen();
+        this.separator = separator;
+    }
+
+    /// All normal List mutators must check the frozen bit:
+    public String set(int index, String o) {
+        checkNotFrozen();
+        return super.set(index, o);
+    }
+
+    public boolean add(String o) {
+        checkNotFrozen();
+        return super.add(o);
+    }
+
+    public void add(int index, String o) {
+        checkNotFrozen();
+        super.add(index, o);
+    }
+
+    public boolean addAll(Collection<? extends String> c) {
+        checkNotFrozen();
+        return super.addAll(c);
+    }
+
+    public boolean addAll(int index, Collection<? extends String> c) {
+        checkNotFrozen();
+        return super.addAll(index, c);
+    }
+
+    public boolean remove(Object o) {
+        checkNotFrozen();
+        return super.remove(o);
+    }
+
+    public String remove(int index) {
+        checkNotFrozen();
+        return super.remove(index);
+    }
+
+    public void clear() {
+        checkNotFrozen();
+        super.clear();
+    }
+
+    /** Add a collection of tokens to the list, applying toString to each. */
+    public boolean addTokens(Collection<? extends Object> tokens) {
+        // Note that if this sequence is empty, no tokens are added.
+        // This is different from adding a null string, which is
+        // a single token.
+        boolean added = false;
+        for (Object token : tokens) {
+            add(token.toString());
+            added = true;
+        }
+        return added;
+    }
+
+    public boolean addTokens(Object[] tokens, int beg, int end) {
+        boolean added = false;
+        for (int i = beg; i < end; i++) {
+            add(tokens[i].toString());
+            added = true;
+        }
+        return added;
+    }
+
+    public boolean addTokens(String tokenStr) {
+        return addTokens(tokenStr, false);
+    }
+
+    public boolean addTokens(String tokenStr, boolean allowNulls) {
+        boolean added = false;
+        int pos = 0, limit = tokenStr.length(), sep = limit;
+        while (pos < limit) {
+            sep = tokenStr.indexOf(separator, pos);
+            if (sep < 0) {
+                sep = limit;
+            }
+            if (sep == pos) {
+                if (allowNulls) {
+                    add("");
+                    added = true;
+                }
+                pos += separator.length();
+            } else {
+                add(tokenStr.substring(pos, sep));
+                added = true;
+                pos = sep + separator.length();
+            }
+        }
+        if (allowNulls && sep < limit) {
+            // Input was something like "tok1 tok2 ".
+            add("");
+            added = true;
+        }
+        return added;
+    }
+
+    public boolean addToken(Object token) {
+        return add(token.toString());
+    }
+
+    /** Format the token string, using quotes and escapes.
+     *  Quotes must contain an odd number of 3 or more elements,
+     *  a sequence of begin/end quote pairs, plus a superquote.
+     *  For each token, the first begin/end pair is used for
+     *  which the end quote does not occur in the token.
+     *  If the token contains all end quotes, the last pair
+     *  is used, with all occurrences of the end quote replaced
+     *  by the superquote.  If an end quote is the empty string,
+     *  the separator is used instead.
+     */
+    public String format(String separator, String[] quotes) {
+        return ""; //@@
+    }
+    protected int[] lengths;
+    protected static final int MODC = 0, HINT = 1, BEG0 = 2, END0 = 3;
+
+    // Layout of lengths:
+    //   { modCount, hint, -1==beg[0], end[0]==beg[1], ..., length }
+    // Note that each beg[i]..end[i] span includes a leading separator,
+    // which is not part of the corresponding token.
+    protected final CharSequence getCS(int i) {
+        return (CharSequence) get(i);
+    }
+
+    // Produce (and cache) an table of indexes for each token.
+    protected int[] getLengths() {
+        int[] lengths = this.lengths;
+        ;
+        int sepLength = separator.length();
+        if (lengths == null || lengths[MODC] != modCount) {
+            int size = this.size();
+            lengths = new int[END0 + size + (size == 0 ? 1 : 0)];
+            lengths[MODC] = modCount;
+            int end = -sepLength;  // cancels leading separator
+            lengths[BEG0] = end;
+            for (int i = 0; i < size; i++) {
+                end += sepLength;  // count leading separator
+                end += getCS(i).length();
+                lengths[END0 + i] = end;
+            }
+            this.lengths = lengths;
+        }
+        return lengths;
+    }
+
+    public int length() {
+        int[] lengths = getLengths();
+        return lengths[lengths.length - 1];
+    }
+
+    // Which token does the given index belong to?
+    protected int which(int i) {
+        if (i < 0) {
+            return -1;
+        }
+        int[] lengths = getLengths();
+        for (int hint = lengths[HINT];; hint = 0) {
+            for (int wh = hint; wh < lengths.length - END0; wh++) {
+                int beg = lengths[BEG0 + wh];
+                int end = lengths[END0 + wh];
+                if (i >= beg && i < end) {
+                    lengths[HINT] = wh;
+                    return wh;
+                }
+            }
+            if (hint == 0) {
+                return size();  // end of the line
+            }
+        }
+    }
+
+    public char charAt(int i) {
+        if (i < 0) {
+            return "".charAt(i);
+        }
+        int wh = which(i);
+        int beg = lengths[BEG0 + wh];
+        int j = i - beg;
+        int sepLength = separator.length();
+        if (j < sepLength) {
+            return separator.charAt(j);
+        }
+        return getCS(wh).charAt(j - sepLength);
+    }
+
+    public CharSequence subSequence(int beg, int end) {
+        //System.out.println("i: "+beg+".."+end);
+        if (beg == end) {
+            return "";
+        }
+        if (beg < 0) {
+            charAt(beg);  // raise exception
+        }
+        if (beg > end) {
+            charAt(-1);   // raise exception
+        }
+        int begWh = which(beg);
+        int endWh = which(end);
+        if (endWh == size() || end == lengths[BEG0 + endWh]) {
+            --endWh;
+        }
+        //System.out.println("wh: "+begWh+".."+endWh);
+        int begBase = lengths[BEG0 + begWh];
+        int endBase = lengths[BEG0 + endWh];
+        int sepLength = separator.length();
+        int begFrag = 0;
+        if ((beg - begBase) < sepLength) {
+            begFrag = sepLength - (beg - begBase);
+            beg += begFrag;
+        }
+        int endFrag = 0;
+        if ((end - endBase) < sepLength) {
+            endFrag = (end - endBase);
+            end = endBase;
+            endBase = lengths[BEG0 + --endWh];
+        }
+        if (false) {
+            System.out.print("beg[wbf]end[wbf]");
+            int pr[] = {begWh, begBase, begFrag, beg, endWh, endBase, endFrag, end};
+            for (int k = 0; k < pr.length; k++) {
+                System.out.print((k == 4 ? "   " : " ") + (pr[k]));
+            }
+            System.out.println();
+        }
+        if (begFrag > 0 && (end + endFrag) - begBase <= sepLength) {
+            // Special case:  Slice the separator.
+            beg -= begFrag;
+            end += endFrag;
+            return separator.substring(beg - begBase, end - begBase);
+        }
+        if (begWh == endWh && (begFrag + endFrag) == 0) {
+            // Special case:  Slice a single token.
+            return getCS(begWh).subSequence(beg - begBase - sepLength,
+                    end - endBase - sepLength);
+        }
+        Object[] subTokens = new Object[1 + (endWh - begWh) + 1];
+        int fillp = 0;
+        if (begFrag == sepLength) {
+            // Insert a leading null token to force an initial separator.
+            subTokens[fillp++] = "";
+            begFrag = 0;
+        }
+        for (int wh = begWh; wh <= endWh; wh++) {
+            CharSequence cs = getCS(wh);
+            if (wh == begWh || wh == endWh) {
+                // Slice it.
+                int csBeg = (wh == begWh) ? (beg - begBase) - sepLength : 0;
+                int csEnd = (wh == endWh) ? (end - endBase) - sepLength : cs.length();
+                cs = cs.subSequence(csBeg, csEnd);
+                if (begFrag > 0 && wh == begWh) {
+                    cs = separator.substring(sepLength - begFrag) + cs;
+                }
+                if (endFrag > 0 && wh == endWh) {
+                    cs = cs.toString() + separator.substring(0, endFrag);
+                }
+            }
+            subTokens[fillp++] = cs;
+        }
+        return new TokenList(subTokens, 0, fillp, separator);
+    }
+
+    /** Returns the concatenation of all tokens,
+     *  with intervening separator characters.
+     */
+    public String toString() {
+        StringBuilder buf = new StringBuilder(length());
+        int size = this.size();
+        for (int i = 0; i < size; i++) {
+            if (i > 0) {
+                buf.append(separator);
+            }
+            buf.append(get(i));
+        }
+        return buf.toString();
+    }
+
+    /*---- TESTING CODE ----
+    public static void main(String[] av) {
+    if (av.length == 0)  av = new String[]{"one", "2", "", "four"};
+    TokenList ts = new TokenList();
+    final String SEP = ", ";
+    ts.setSeparator(SEP);
+    for (int i = -1; i < av.length; i++) {
+    if (i >= 0)  ts.addToken(av[i]);
+    {
+    TokenList tsCopy = new TokenList(ts.toString(), SEP);
+    if (!tsCopy.equals(ts)) {
+    tsCopy.setSeparator(")(");
+    System.out.println("!= ("+tsCopy+")");
+    }
+    }
+    {
+    TokenList tsBar = new TokenList(ts, "|");
+    tsBar.add(0, "[");
+    tsBar.add("]");
+    System.out.println(tsBar);
+    }
+    if (false) {
+    int[] ls = ts.getLengths();
+    System.out.println("ts: "+ts);
+    System.out.print("ls: {");
+    for (int j = 0; j < ls.length; j++)  System.out.print(" "+ls[j]);
+    System.out.println(" }");
+    }
+    assert0(ts.size() == i+1);
+    assert0(i < 0 || ts.get(i) == av[i]);
+    String tss = ts.toString();
+    int tslen = tss.length();
+    assert0(ts.length() == tss.length());
+    for (int n = 0; n < tslen; n++) {
+    assert0(ts.charAt(n) == tss.charAt(n));
+    }
+    for (int j = 0; j < tslen; j++) {
+    for (int k = tslen; k >= j; k--) {
+    CharSequence sub = ts.subSequence(j, k);
+    //System.out.println("|"+sub+"|");
+    assert0(sub.toString().equals(tss.substring(j, k)));
+    }
+    }
+    }
+    }
+    static void assert0(boolean z) {
+    if (!z)  throw new RuntimeException("assert failed");
+    }
+    // ---- TESTING CODE ----*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java	Thu Sep 02 12:17:21 2010 -0700
@@ -0,0 +1,4330 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
+
+// XML Implementation packages:
+import java.util.*;
+
+import java.io.Reader;
+import java.io.Writer;
+import java.io.OutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.BufferedReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.StringReader;
+
+import java.io.IOException;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.InputSource;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.Attributes;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * A kit of methods and classes useful for manipulating XML trees in
+ * memory. They are very compact and easy to use. An XML element
+ * occupies six pointers of overhead (like two arrays) plus a pointer
+ * for its name, each attribute name and value, and each sub-element.
+ * Many useful XML operations (or Lisp-like calls) can be accomplished
+ * with a single method call on an element itself.
+ * <p>
+ * There is strong integration with the Java collection classes.
+ * There are viewing and conversion operators to and from various
+ * collection types. Elements directly support list iterators.
+ * Most <tt>List</tt> methods work analogously on elements.
+ * <p>
+ * Because of implementation compromises, these XML trees are less
+ * functional than many standard XML classes.
+ * <ul>
+ * <li>There are no parent or sibling pointers in the tree.</li>
+ * <li>Attribute names are simple strings, with no namespaces.</li>
+ * <li>There is no internal support for schemas or validation.</li>
+ * </ul>
+ * <p>
+ * Here is a summary of functionality in <tt>XMLKit</tt>.
+ * (Overloaded groups of methods are summarized by marking some
+ * arguments optional with their default values. Some overloaded
+ * arguments are marked with their alternative types separated by
+ * a bar "|". Arguments or return values for which a null is
+ * specially significant are marked by an alternative "|null".
+ * Accessors which have corresponding setters are marked
+ * by "/set". Removers which have corresponding retainers are marked
+ * by "/retain".)
+ * <pre>
+ * --- element construction
+ * new Element(int elemCapacity=4), String name=""
+ * new Element(String name, String[] attrs={}, Element[] elems={}, int elemCapacity=4)
+ * new Element(String name, String[] attrs, Object[] elems, int elemCapacity=4)
+ * new Element(Element original) // shallow copy
+ * new Element(String name="", Collection elems) // coercion
+ *
+ * Element shallowCopy()
+ * Element shallowFreeze() // side-effecting
+ * Element deepCopy()
+ * Element deepFreeze() // not side-effecting
+ *
+ * EMPTY // frozen empty anonymous element
+ * void ensureExtraCapacity(int)
+ * void trimToSize()
+ * void sortAttrs() // sort by key
+ *
+ * --- field accessors
+ * String getName()/set
+ * int size()
+ * boolean isEmpty()
+ * boolean isFrozen()
+ * boolean isAnonymous()
+ * int getExtraCapacity()/set
+ * int attrSize()
+ *
+ * --- attribute accessors
+ * String getAttr(int i)/set
+ * String getAttrName(int i)
+ *
+ * String getAttr(String key)/set
+ * List getAttrList(String key)/set
+ * Number getAttrNumber(String key)/set
+ * long getAttrLong(String key)/set
+ * double getAttrDouble(String key)/set
+ *
+ * String getAttr(String key, String dflt=null)
+ * long getAttrLong(String key, long dflt=0)
+ * double getAttrDouble(String key, double dflt=0)
+ *
+ * Element copyAttrsOnly()
+ * Element getAttrs()/set =&gt; <em>&lt;&gt;&lt;key&gt;value&lt;/key&gt;...&lt;/&gt;</em>
+ * void addAttrs(Element attrs)
+ *
+ * void removeAttr(int i)
+ * void clearAttrs()
+ *
+ * --- element accessors
+ * Object get(int i)/set
+ * Object getLast() | null
+ * Object[] toArray()
+ * Element copyContentOnly()
+ *
+ * void add(int i=0, Object subElem)
+ * int addAll(int i=0, Collection | Element elems)
+ * int addContent(int i=0, TokenList|Element|Object|null)
+ * void XMLKit.addContent(TokenList|Element|Object|null, Collection sink|null)
+ *
+ * void clear(int beg=0, int end=size)
+ * void sort(Comparator=contentOrder())
+ * void reverse()
+ * void shuffle(Random rnd=(anonymous))
+ * void rotate(int distance)
+ * Object min/max(Comparator=contentOrder())
+ *
+ * --- text accessors
+ * CharSequence getText()/set
+ * CharSequence getUnmarkedText()
+ * int addText(int i=size, CharSequence)
+ * void trimText();
+ *
+ * --- views
+ * List asList() // element view
+ * ListIterator iterator()
+ * PrintWriter asWriter()
+ * Map asAttrMap()
+ * Iterable<CharSequence> texts()
+ * Iterable<Element> elements()
+ * Iterable<T> partsOnly(Class<T>)
+ * String[] toStrings()
+ *
+ * --- queries
+ * boolean equals(Element | Object)
+ * int compareTo(Element | Object)
+ * boolean equalAttrs(Element)
+ * int hashCode()
+ * boolean isText() // every sub-elem is CharSequence
+ * boolean hasText() // some sub-elem is CharSequence
+ *
+ * boolean contains(Object)
+ * boolean containsAttr(String)
+ *
+ * int indexOf(Object)
+ * int indexOf(Filter, int fromIndex=0)
+ * int lastIndexOf(Object)
+ * int lastIndexOf(Filter, int fromIndex=size-1)
+ *
+ * int indexOfAttr(String)
+ *
+ * // finders, removers, and replacers do addContent of each filtered value
+ * // (i.e., TokenLists and anonymous Elements are broken out into their parts)
+ * boolean matches(Filter)
+ *
+ * Object find(Filter, int fromIndex=0)
+ * Object findLast(Filter, int fromIndex=size-1)
+ * Element findAll(Filter, int fromIndex=0 &amp; int toIndex=size)
+ * int findAll(Filter, Collection sink | null, int fromIndex=0 &amp; int toIndex=size)
+ *
+ * Element removeAllInTree(Filter)/retain
+ * int findAllInTree(Filter, Collection sink | null)
+ * int countAllInTree(Filter)
+ * Element removeAllInTree(Filter)/retain
+ * int removeAllInTree(Filter, Collection sink | null)/retain
+ * void replaceAllInTree(Filter)
+ *
+ * Element findElement(String name=any)
+ * Element findAllElements(String name=any)
+ *
+ * Element findWithAttr(String key, String value=any)
+ * Element findAllWithAttr(String key, String value=any)
+ *
+ * Element removeElement(String name=any)
+ * Element removeAllElements(String name=any)/retain
+ *
+ * Element removeWithAttr(String key, String value=any)
+ * Element removeAllWithAttr(String key, String value=any)/retain
+ *
+ * //countAll is the same as findAll but with null sink
+ * int countAll(Filter)
+ * int countAllElements(String name=any)
+ * int countAllWithAttr(String key, String value=any)
+ *
+ * void replaceAll(Filter, int fromIndex=0 &amp; int toIndex=size)
+ * void replaceAllInTree(Filter)
+ * void XMLKit.replaceAll(Filter, List target) //if(fx){remove x;addContent fx}
+ *
+ * --- element mutators
+ * boolean remove(Object)
+ * Object remove(int)
+ * Object removeLast() | null
+ *
+ * Object remove(Filter, int fromIndex=0)
+ * Object removeLast(Filter, int fromIndex=size-1)
+ * Element sink = removeAll(Filter, int fromIndex=0 &amp; int toIndex=size)/retain
+ * int count = removeAll(Filter, int fromIndex=0 &amp; int toIndex=size, Collection sink | null)/retain
+ *
+ * Element removeAllElements(String name=any)
+ *
+ * --- attribute mutators
+ * ??int addAllAttrsFrom(Element attrSource)
+ *
+ * --- parsing and printing
+ * void tokenize(String delims=whitespace, returnDelims=false)
+ * void writeTo(Writer)
+ * void writePrettyTo(Writer)
+ * String prettyString()
+ * String toString()
+ *
+ * ContentHandler XMLKit.makeBuilder(Collection sink, tokenizing=false, makeFrozen=false) // for standard XML parser
+ * Element XMLKit.readFrom(Reader, tokenizing=false, makeFrozen=false)
+ * void XMLKit.prettyPrintTo(Writer | OutputStream, Element)
+ * class XMLKit.Printer(Writer) { void print/Recursive(Element) }
+ * void XMLKit.output(Object elem, ContentHandler, LexicalHandler=null)
+ * void XMLKit.writeToken(String, char quote, Writer)
+ * void XMLKit.writeCData(String, Writer)
+ * Number XMLKit.convertToNumber(String, Number dflt=null)
+ * long XMLKit.convertToLong(String, long dflt=0)
+ * double XMLKit.convertToDouble(String, double dflt=0)
+ *
+ * --- filters
+ * XMLKit.ElementFilter { Element filter(Element) }
+ * XMLKit.elementFilter(String name=any | Collection nameSet)
+ * XMLKit.AttrFilter(String key) { boolean test(String value) }
+ * XMLKit.attrFilter(String key, String value=any)
+ * XMLKit.attrFilter(Element matchThis, String key)
+ * XMLKit.classFilter(Class)
+ * XMLKit.textFilter() // matches any CharSequence
+ * XMLKit.specialFilter() // matches any Special element
+ * XMLKit.methodFilter(Method m, Object[] args=null, falseResult=null)
+ * XMLKit.testMethodFilter(Method m, Object[] args=null)
+ * XMLKit.not(Filter) // inverts sense of Filter
+ * XMLKit.and(Filter&amp;Filter | Filter[])
+ * XMLKit.or(Filter&amp;Filter | Filter[])
+ * XMLKit.stack(Filter&amp;Filter | Filter[]) // result is (fx && g(fx))
+ * XMLKit.content(Filter, Collection sink) // copies content to sink
+ * XMLKit.replaceInTree(Filter pre, Filter post=null) // pre-replace else recur
+ * XMLKit.findInTree(Filter pre, Collection sink=null) // pre-find else recur
+ * XMLKit.nullFilter() // ignores input, always returns null (i.e., false)
+ * XMLKit.selfFilter( ) // always returns input (i.e., true)
+ * XMLKit.emptyFilter() // ignores input, always returns EMPTY
+ * XMLKit.constantFilter(Object) // ignores input, always returns constant
+ *
+ * --- misc
+ * Comparator XMLKit.contentOrder() // for comparing/sorting mixed content
+ * Method XMLKit.Element.method(String name) // returns Element method
+ * </pre>
+ *
+ * @author jrose
+ */
+public abstract class XMLKit {
+
+    private XMLKit() {
+    }
+    // We need at least this much slop if the element is to stay unfrozen.
+    static final int NEED_SLOP = 1;
+    static final Object[] noPartsFrozen = {};
+    static final Object[] noPartsNotFrozen = new Object[NEED_SLOP];
+    static final String WHITESPACE_CHARS = " \t\n\r\f";
+    static final String ANON_NAME = new String("*");  // unique copy of "*"
+
+    public static final class Element implements Comparable<Element>, Iterable<Object> {
+        // Note:  Does not implement List, because it has more
+        // significant parts besides its sub-elements.  Therefore,
+        // hashCode and equals must be more distinctive than Lists.
+
+        // <name> of element
+        String name;
+        // number of child elements, in parts[0..size-1]
+        int size;
+        // The parts start with child elements::  {e0, e1, e2, ...}.
+        // Following that are optional filler elements, all null.
+        // Following that are attributes as key/value pairs.
+        // They are in reverse: {...key2, val2, key1, val1, key0, val0}.
+        // Child elements and attr keys and values are never null.
+        Object[] parts;
+
+        // Build a partially-constructed node.
+        // Caller is responsible for initializing promised attributes.
+        Element(String name, int size, int capacity) {
+            this.name = name.toString();
+            this.size = size;
+            assert (size <= capacity);
+            this.parts = capacity > 0 ? new Object[capacity] : noPartsFrozen;
+        }
+
+        /** An anonymous, empty element.
+         *  Optional elemCapacity argument is expected number of sub-elements.
+         */
+        public Element() {
+            this(ANON_NAME, 0, NEED_SLOP + 4);
+        }
+
+        public Element(int extraCapacity) {
+            this(ANON_NAME, 0, NEED_SLOP + Math.max(0, extraCapacity));
+        }
+
+        /** An empty element with the given name.
+         *  Optional extraCapacity argument is expected number of sub-elements.
+         */
+        public Element(String name) {
+            this(name, 0, NEED_SLOP + 4);
+        }
+
+        public Element(String name, int extraCapacity) {
+            this(name, 0, NEED_SLOP + Math.max(0, extraCapacity));
+        }
+
+        /** An empty element with the given name and attributes.
+         *  Optional extraCapacity argument is expected number of sub-elements.
+         */
+        public Element(String name, String... attrs) {
+            this(name, attrs, (Element[]) null, 0);
+        }
+
+        public Element(String name, String[] attrs, int extraCapacity) {
+            this(name, attrs, (Element[]) null, extraCapacity);
+        }
+
+        /** An empty element with the given name and sub-elements.
+         *  Optional extraCapacity argument is expected extra sub-elements.
+         */
+        public Element(String name, Element... elems) {
+            this(name, (String[]) null, elems, 0);
+        }
+
+        public Element(String name, Element[] elems, int extraCapacity) {
+            this(name, (String[]) null, elems, extraCapacity);
+        }
+
+        /** An empty element with the given name, attributes, and sub-elements.
+         *  Optional extraCapacity argument is expected extra sub-elements.
+         */
+        public Element(String name, String[] attrs, Object... elems) {
+            this(name, attrs, elems, 0);
+        }
+
+        public Element(String name, String[] attrs, Object[] elems, int extraCapacity) {
+            this(name, 0,
+                    ((elems == null) ? 0 : elems.length)
+                    + Math.max(0, extraCapacity)
+                    + NEED_SLOP
+                    + ((attrs == null) ? 0 : attrs.length));
+            int ne = ((elems == null) ? 0 : elems.length);
+            int na = ((attrs == null) ? 0 : attrs.length);
+            int fillp = 0;
+            for (int i = 0; i < ne; i++) {
+                if (elems[i] != null) {
+                    parts[fillp++] = elems[i];
+                }
+            }
+            size = fillp;
+            for (int i = 0; i < na; i += 2) {
+                setAttr(attrs[i + 0], attrs[i + 1]);
+            }
+        }
+
+        public Element(Collection c) {
+            this(c.size());
+            addAll(c);
+        }
+
+        public Element(String name, Collection c) {
+            this(name, c.size());
+            addAll(c);
+        }
+
+        /** Shallow copy.  Same as old.shallowCopy().
+         *  Optional extraCapacity argument is expected extra sub-elements.
+         */
+        public Element(Element old) {
+            this(old, 0);
+        }
+
+        public Element(Element old, int extraCapacity) {
+            this(old.name, old.size,
+                    old.size
+                    + Math.max(0, extraCapacity) + NEED_SLOP
+                    + old.attrLength());
+            // copy sub-elements
+            System.arraycopy(old.parts, 0, parts, 0, size);
+            int alen = parts.length
+                    - (size + Math.max(0, extraCapacity) + NEED_SLOP);
+            // copy attributes
+            System.arraycopy(old.parts, old.parts.length - alen,
+                    parts, parts.length - alen,
+                    alen);
+            assert (!isFrozen());
+        }
+
+        /** Shallow copy.  Same as new Element(this). */
+        public Element shallowCopy() {
+            return new Element(this);
+        }
+        static public final Element EMPTY = new Element(ANON_NAME, 0, 0);
+
+        Element deepFreezeOrCopy(boolean makeFrozen) {
+            if (makeFrozen && isFrozen()) {
+                return this;  // no need to copy it
+            }
+            int alen = attrLength();
+            int plen = size + (makeFrozen ? 0 : NEED_SLOP) + alen;
+            Element copy = new Element(name, size, plen);
+            // copy attributes
+            System.arraycopy(parts, parts.length - alen, copy.parts, plen - alen, alen);
+            // copy sub-elements
+            for (int i = 0; i < size; i++) {
+                Object e = parts[i];
+                String str;
+                if (e instanceof Element) {  // recursion is common case
+                    e = ((Element) e).deepFreezeOrCopy(makeFrozen);
+                } else if (makeFrozen) {
+                    // Freeze StringBuffers, etc.
+                    e = fixupString(e);
+                }
+                copy.setRaw(i, e);
+            }
+            return copy;
+        }
+
+        /** Returns new Element(this), and also recursively copies sub-elements. */
+        public Element deepCopy() {
+            return deepFreezeOrCopy(false);
+        }
+
+        /** Returns frozen version of deepCopy. */
+        public Element deepFreeze() {
+            return deepFreezeOrCopy(true);
+        }
+
+        /** Freeze this element.
+         *  Throw an IllegalArgumentException if any sub-element is not already frozen.
+         *  (Use deepFreeze() to make a frozen copy of an entire element tree.)
+         */
+        public void shallowFreeze() {
+            if (isFrozen()) {
+                return;
+            }
+            int alen = attrLength();
+            Object[] nparts = new Object[size + alen];
+            // copy attributes
+            System.arraycopy(parts, parts.length - alen, nparts, size, alen);
+            // copy sub-elements
+            for (int i = 0; i < size; i++) {
+                Object e = parts[i];
+                String str;
+                if (e instanceof Element) {  // recursion is common case
+                    if (!((Element) e).isFrozen()) {
+                        throw new IllegalArgumentException("Sub-element must be frozen.");
+                    }
+                } else {
+                    // Freeze StringBuffers, etc.
+                    e = fixupString(e);
+                }
+                nparts[i] = e;
+            }
+            parts = nparts;
+            assert (isFrozen());
+        }
+
+        /** Return the name of this element. */
+        public String getName() {
+            return name;
+        }
+
+        /** Change the name of this element. */
+        public void setName(String name) {
+            checkNotFrozen();
+            this.name = name.toString();
+        }
+
+        /** Reports if the element's name is a particular string (spelled "*").
+         *  Such elements are created by the nullary Element constructor,
+         *  and by query functions which return multiple values,
+         *  such as <tt>findAll</tt>.
+         */
+        public boolean isAnonymous() {
+            return name == ANON_NAME;
+        }
+
+        /** Return number of elements.  (Does not include attributes.) */
+        public int size() {
+            return size;
+        }
+
+        /** True if no elements.  (Does not consider attributes.) */
+        public boolean isEmpty() {
+            return size == 0;
+        }
+
+        /** True if this element does not allow modification. */
+        public boolean isFrozen() {
+            // It is frozen iff there is no slop space.
+            return !hasNulls(NEED_SLOP);
+        }
+
+        void checkNotFrozen() {
+            if (isFrozen()) {
+                throw new UnsupportedOperationException("cannot modify frozen element");
+            }
+        }
+
+        /** Remove specified elements.  (Does not affect attributes.) */
+        public void clear() {
+            clear(0, size);
+        }
+
+        public void clear(int beg) {
+            clear(beg, size);
+        }
+
+        public void clear(int beg, int end) {
+            if (end > size) {
+                badIndex(end);
+            }
+            if (beg < 0 || beg > end) {
+                badIndex(beg);
+            }
+            if (beg == end) {
+                return;
+            }
+            checkNotFrozen();
+            if (end == size) {
+                if (beg == 0
+                        && parts.length > 0 && parts[parts.length - 1] == null) {
+                    // If no attributes, free the parts array.
+                    parts = noPartsNotFrozen;
+                    size = 0;
+                } else {
+                    clearParts(beg, size);
+                    size = beg;
+                }
+            } else {
+                close(beg, end - beg);
+            }
+        }
+
+        void clearParts(int beg, int end) {
+            for (int i = beg; i < end; i++) {
+                parts[i] = null;
+            }
+        }
+
+        /** True if name, attributes, and elements are the same. */
+        public boolean equals(Element that) {
+            if (!this.name.equals(that.name)) {
+                return false;
+            }
+            if (this.size != that.size) {
+                return false;
+            }
+            // elements must be equal and ordered
+            Object[] thisParts = this.parts;
+            Object[] thatParts = that.parts;
+            for (int i = 0; i < size; i++) {
+                Object thisPart = thisParts[i];
+                Object thatPart = thatParts[i];
+
+                if (thisPart instanceof Element) { // recursion is common case
+                    if (!thisPart.equals(thatPart)) {
+                        return false;
+                    }
+                } else {
+                    // If either is a non-string char sequence, normalize it.
+                    thisPart = fixupString(thisPart);
+                    thatPart = fixupString(thatPart);
+                    if (!thisPart.equals(thatPart)) {
+                        return false;
+                    }
+                }
+            }
+            // finally, attributes must be equal (unordered)
+            return this.equalAttrs(that);
+        }
+        // bridge method
+
+        public boolean equals(Object o) {
+            if (!(o instanceof Element)) {
+                return false;
+            }
+            return equals((Element) o);
+        }
+
+        public int hashCode() {
+            int hc = 0;
+            int alen = attrLength();
+            for (int i = parts.length - alen; i < parts.length; i += 2) {
+                hc += (parts[i + 0].hashCode() ^ parts[i + 1].hashCode());
+            }
+            hc ^= hc << 11;
+            hc += name.hashCode();
+            for (int i = 0; i < size; i++) {
+                hc ^= hc << 7;
+                Object p = parts[i];
+                if (p instanceof Element) {
+                    hc += p.hashCode();  // recursion is common case
+                } else {
+                    hc += fixupString(p).hashCode();
+                }
+            }
+            hc ^= hc >>> 19;
+            return hc;
+        }
+
+        /** Compare lexicographically.  Earlier-spelled attrs are more sigificant. */
+        public int compareTo(Element that) {
+            int r;
+            // Primary key is element name.
+            r = this.name.compareTo(that.name);
+            if (r != 0) {
+                return r;
+            }
+
+            // Secondary key is attributes, as if in normal key order.
+            // The key/value pairs are sorted as a token sequence.
+            int thisAlen = this.attrLength();
+            int thatAlen = that.attrLength();
+            if (thisAlen != 0 || thatAlen != 0) {
+                r = compareAttrs(thisAlen, that, thatAlen, true);
+                assert (assertAttrCompareOK(r, that));
+                if (r != 0) {
+                    return r;
+                }
+            }
+
+            // Finally, elements should be equal and ordered,
+            // and the first difference rules.
+            Object[] thisParts = this.parts;
+            Object[] thatParts = that.parts;
+            int minSize = this.size;
+            if (minSize > that.size) {
+                minSize = that.size;
+            }
+            Comparator<Object> cc = contentOrder();
+            for (int i = 0; i < minSize; i++) {
+                r = cc.compare(thisParts[i], thatParts[i]);
+                if (r != 0) {
+                    return r;
+                }
+            }
+            //if (this.size < that.size)  return -1;
+            return this.size - that.size;
+        }
+
+        private boolean assertAttrCompareOK(int r, Element that) {
+            Element e0 = this.copyAttrsOnly();
+            Element e1 = that.copyAttrsOnly();
+            e0.sortAttrs();
+            e1.sortAttrs();
+            int r2;
+            for (int k = 0;; k++) {
+                boolean con0 = e0.containsAttr(k);
+                boolean con1 = e1.containsAttr(k);
+                if (con0 != con1) {
+                    if (!con0) {
+                        r2 = 0 - 1;
+                        break;
+                    }
+                    if (!con1) {
+                        r2 = 1 - 0;
+                        break;
+                    }
+                }
+                if (!con0) {
+                    r2 = 0;
+                    break;
+                }
+                String k0 = e0.getAttrName(k);
+                String k1 = e1.getAttrName(k);
+                r2 = k0.compareTo(k1);
+                if (r2 != 0) {
+                    break;
+                }
+                String v0 = e0.getAttr(k);
+                String v1 = e1.getAttr(k);
+                r2 = v0.compareTo(v1);
+                if (r2 != 0) {
+                    break;
+                }
+            }
+            if (r != 0) {
+                r = (r > 0) ? 1 : -1;
+            }
+            if (r2 != 0) {
+                r2 = (r2 > 0) ? 1 : -1;
+            }
+            if (r != r2) {
+                System.out.println("*** wrong attr compare, " + r + " != " + r2);
+                System.out.println(" this = " + this);
+                System.out.println("  attr->" + e0);
+                System.out.println(" that = " + that);
+                System.out.println("  attr->" + e1);
+            }
+            return r == r2;
+        }
+
+        private void badIndex(int i) {
+            Object badRef = (new Object[0])[i];
+        }
+
+        public Object get(int i) {
+            if (i >= size) {
+                badIndex(i);
+            }
+            return parts[i];
+        }
+
+        public Object set(int i, Object e) {
+            if (i >= size) {
+                badIndex(i);
+            }
+            e.getClass();  // null check
+            checkNotFrozen();
+            Object old = parts[i];
+            setRaw(i, e);
+            return old;
+        }
+
+        void setRaw(int i, Object e) {
+            parts[i] = e;
+        }
+
+        public boolean remove(Object e) {
+            int i = indexOf(e);
+            if (i < 0) {
+                return false;
+            }
+            close(i, 1);
+            return true;
+        }
+
+        public Object remove(int i) {
+            if (i >= size) {
+                badIndex(i);
+            }
+            Object e = parts[i];
+            close(i, 1);
+            return e;
+        }
+
+        public Object removeLast() {
+            if (size == 0) {
+                return null;
+            }
+            return remove(size - 1);
+        }
+
+        /** Remove the first element matching the given filter.
+         *  Return the filtered value.
+         */
+        public Object remove(Filter f) {
+            return findOrRemove(f, 0, true);
+        }
+
+        public Object remove(Filter f, int fromIndex) {
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+            return findOrRemove(f, fromIndex, true);
+        }
+
+        /** Remove the last element matching the given filter.
+         *  Return the filtered value.
+         */
+        public Object removeLast(Filter f) {
+            return findOrRemoveLast(f, size - 1, true);
+        }
+
+        public Object removeLast(Filter f, int fromIndex) {
+            if (fromIndex >= size) {
+                fromIndex = size - 1;
+            }
+            return findOrRemoveLast(f, fromIndex, true);
+        }
+
+        /** Remove all elements matching the given filter.
+         *  If there is a non-null collection given as a sink,
+         *  transfer removed elements to the given collection.
+         *  The int result is the number of removed elements.
+         *  If there is a null sink given, the removed elements
+         *  are discarded.  If there is no sink given, the removed
+         *  elements are returned in an anonymous container element.
+         */
+        public Element removeAll(Filter f) {
+            Element result = new Element();
+            findOrRemoveAll(f, false, 0, size, result.asList(), true);
+            return result;
+        }
+
+        public Element removeAll(Filter f, int fromIndex, int toIndex) {
+            Element result = new Element();
+            findOrRemoveAll(f, true, fromIndex, toIndex, result.asList(), true);
+            return result;
+        }
+
+        public int removeAll(Filter f, Collection<Object> sink) {
+            return findOrRemoveAll(f, false, 0, size, sink, true);
+        }
+
+        public int removeAll(Filter f, int fromIndex, int toIndex, Collection<Object> sink) {
+            return findOrRemoveAll(f, false, fromIndex, toIndex, sink, true);
+        }
+
+        /** Remove all elements not matching the given filter.
+         *  If there is a non-null collection given as a sink,
+         *  transfer removed elements to the given collection.
+         *  The int result is the number of removed elements.
+         *  If there is a null sink given, the removed elements
+         *  are discarded.  If there is no sink given, the removed
+         *  elements are returned in an anonymous container element.
+         */
+        public Element retainAll(Filter f) {
+            Element result = new Element();
+            findOrRemoveAll(f, true, 0, size, result.asList(), true);
+            return result;
+        }
+
+        public Element retainAll(Filter f, int fromIndex, int toIndex) {
+            Element result = new Element();
+            findOrRemoveAll(f, true, fromIndex, toIndex, result.asList(), true);
+            return result;
+        }
+
+        public int retainAll(Filter f, Collection<Object> sink) {
+            return findOrRemoveAll(f, true, 0, size, sink, true);
+        }
+
+        public int retainAll(Filter f, int fromIndex, int toIndex, Collection<Object> sink) {
+            return findOrRemoveAll(f, true, fromIndex, toIndex, sink, true);
+        }
+
+        public void add(int i, Object e) {
+            // (The shape of this method is tweaked for common cases.)
+            e.getClass();  // force a null check on e
+            if (hasNulls(1 + NEED_SLOP)) {
+                // Common case:  Have some slop space.
+                if (i == size) {
+                    // Most common case:  Append.
+                    setRaw(i, e);
+                    size++;
+                    return;
+                }
+                if (i > size) {
+                    badIndex(i);
+                }
+                // Second most common case:  Shift right by one.
+                open(i, 1);
+                setRaw(i, e);
+                return;
+            }
+            // Ran out of space.  Do something complicated.
+            size = expand(i, 1);
+            setRaw(i, e);
+        }
+
+        public boolean add(Object e) {
+            add(size, e);
+            return true;
+        }
+
+        public Object getLast() {
+            return size == 0 ? null : parts[size - 1];
+        }
+
+        /** Returns the text of this Element.
+         *  All sub-elements of this Element must be of type CharSequence.
+         *  A ClassCastException is raised if there are non-character sub-elements.
+         *  If there is one sub-element, return it.
+         *  Otherwise, returns a TokenList of all sub-elements.
+         *  This results in a space being placed between each adjacent pair of sub-elements.
+         */
+        public CharSequence getText() {
+            checkTextOnly();
+            if (size == 1) {
+                return parts[0].toString();
+            } else {
+                return new TokenList(parts, 0, size);
+            }
+        }
+
+        /** Provides an iterable view of this object as a series of texts.
+         *  All sub-elements of this Element must be of type CharSequence.
+         *  A ClassCastException is raised if there are non-character sub-elements.
+         */
+        public Iterable<CharSequence> texts() {
+            checkTextOnly();
+            return (Iterable<CharSequence>) (Iterable) this;
+        }
+
+        /** Returns an array of strings derived from the sub-elements of this object.
+         *  All sub-elements of this Element must be of type CharSequence.
+         *  A ClassCastException is raised if there are non-character sub-elements.
+         */
+        public String[] toStrings() {
+            //checkTextOnly();
+            String[] result = new String[size];
+            for (int i = 0; i < size; i++) {
+                result[i] = ((CharSequence) parts[i]).toString();
+            }
+            return result;
+        }
+
+        /** Like getText, except that it disregards non-text elements.
+         *  Non-text elements are replaced by their textual contents, if any.
+         *  Text elements which were separated only by non-text element
+         *  boundaries are merged into single tokens.
+         *  <p>
+         *  There is no corresponding setter, since this accessor does
+         *  not report the full state of the element.
+         */
+        public CharSequence getFlatText() {
+            if (size == 1) {
+                // Simple cases.
+                if (parts[0] instanceof CharSequence) {
+                    return parts[0].toString();
+                } else {
+                    return new TokenList();
+                }
+            }
+            if (isText()) {
+                return getText();
+            }
+            // Filter and merge.
+            Element result = new Element(size);
+            boolean merge = false;
+            for (int i = 0; i < size; i++) {
+                Object text = parts[i];
+                if (!(text instanceof CharSequence)) {
+                    // Skip, but erase this boundary.
+                    if (text instanceof Element) {
+                        Element te = (Element) text;
+                        if (!te.isEmpty()) {
+                            result.addText(te.getFlatText());
+                        }
+                    }
+                    merge = true;
+                    continue;
+                }
+                if (merge) {
+                    // Merge w/ previous token.
+                    result.addText((CharSequence) text);
+                    merge = false;
+                } else {
+                    result.add(text);
+                }
+            }
+            if (result.size() == 1) {
+                return (CharSequence) result.parts[0];
+            } else {
+                return result.getText();
+            }
+        }
+
+        /** Return true if all sub-elements are of type CharSequence. */
+        public boolean isText() {
+            for (int i = 0; i < size; i++) {
+                if (!(parts[i] instanceof CharSequence)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /** Return true if at least one sub-element is of type CharSequence. */
+        public boolean hasText() {
+            for (int i = 0; i < size; i++) {
+                if (parts[i] instanceof CharSequence) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /** Raise a ClassCastException if !isText. */
+        public void checkTextOnly() {
+            for (int i = 0; i < size; i++) {
+                ((CharSequence) parts[i]).getClass();
+            }
+        }
+
+        /** Clears out all sub-elements, and replaces them by the given text.
+         *  A ClassCastException is raised if there are non-character sub-elements,
+         *  either before or after the change.
+         */
+        public void setText(CharSequence text) {
+            checkTextOnly();
+            clear();
+            if (text instanceof TokenList) {
+                // TL's contain only strings
+                addAll(0, (TokenList) text);
+            } else {
+                add(text);
+            }
+        }
+
+        /** Add text at the given position, merging with any previous
+         *  text element, but preserving token boundaries where possible.
+         *  <p>
+         *  In all cases, the new value of getText() is the string
+         *  concatenation of the old value of getText() plus the new text.
+         *  <p>
+         *  The total effect is to concatenate the given text to any
+         *  pre-existing text, and to do so efficiently even if there
+         *  are many such concatenations.  Also, getText calls which
+         *  return multiple tokens (in a TokenList) are respected.
+         *  For example, if x is empty, x.addText(y.getText()) puts
+         *  an exact structural copy of y's text into x.
+         *  <p>
+         *  Internal token boundaries in the original text, and in the new
+         *  text (i.e., if it is a TokenList), are preserved.  However,
+         *  at the point where new text joins old text, a StringBuffer
+         *  or new String may be created to join the last old and first
+         *  new token.
+         *  <p>
+         *  If the given text is a TokenList, add the tokens as
+         *  separate sub-elements, possibly merging the first token to
+         *  a previous text item (to avoid making a new token boundary).
+         *  <p>
+         *  If the element preceding position i is a StringBuffer,
+         *  append the first new token to it.
+         *  <p>
+         *  If the preceding element is a CharSequence, replace it by a
+         *  StringBuffer containing both its and the first new token.
+         *  <p>
+         *  If tokens are added after a StringBuffer, freeze it into a String.
+         *  <p>
+         *  Every token not merged into a previous CharSequence is added
+         *  as a new sub-element, starting at position i.
+         *  <p>
+         *  Returns the number of elements added, which is useful
+         *  for further calls to addText.  This number is zero
+         *  if the input string was null, or was successfully
+         *  merged into a StringBuffer at position i-1.
+         *  <p>
+         *  By contrast, calling add(text) always adds a new sub-element.
+         *  In that case, if there is a previous string, a separating
+         *  space is virtually present also, and will be observed if
+         *  getText() is used to return all the text together.
+         */
+        public int addText(int i, CharSequence text) {
+            if (text instanceof String) {
+                return addText(i, (String) text);
+            } else if (text instanceof TokenList) {
+                // Text is a list of tokens.
+                TokenList tl = (TokenList) text;
+                int tlsize = tl.size();
+                if (tlsize == 0) {
+                    return 0;
+                }
+                String token0 = tl.get(0).toString();
+                if (tlsize == 1) {
+                    return addText(i, token0);
+                }
+                if (mergeWithPrev(i, token0, false)) {
+                    // Add the n-1 remaining tokens.
+                    addAll(i, tl.subList(1, tlsize));
+                    return tlsize - 1;
+                } else {
+                    addAll(i, (Collection) tl);
+                    return tlsize;
+                }
+            } else {
+                return addText(i, text.toString());
+            }
+        }
+
+        public int addText(CharSequence text) {
+            return addText(size, text);
+        }
+
+        private // no reason to make this helper public
+                int addText(int i, String text) {
+            if (text.length() == 0) {
+                return 0;  // Trivial success.
+            }
+            if (mergeWithPrev(i, text, true)) {
+                return 0;  // Merged with previous token.
+            }
+            // No previous token.
+            add(i, text);
+            return 1;
+        }
+
+        // Tries to merge token with previous contents.
+        // Returns true if token is successfully disposed of.
+        // If keepSB is false, any previous StringBuffer is frozen.
+        // If keepSB is true, a StringBuffer may be created to hold
+        // the merged token.
+        private boolean mergeWithPrev(int i, String token, boolean keepSB) {
+            if (i == 0) // Trivial success if the token is length zero.
+            {
+                return (token.length() == 0);
+            }
+            Object prev = parts[i - 1];
+            if (prev instanceof StringBuffer) {
+                StringBuffer psb = (StringBuffer) prev;
+                psb.append(token);
+                if (!keepSB) {
+                    parts[i - 1] = psb.toString();
+                }
+                return true;
+            }
+            if (token.length() == 0) {
+                return true;  // Trivial success.
+            }
+            if (prev instanceof CharSequence) {
+                // Must concatenate.
+                StringBuffer psb = new StringBuffer(prev.toString());
+                psb.append(token);
+                if (keepSB) {
+                    parts[i - 1] = psb;
+                } else {
+                    parts[i - 1] = psb.toString();
+                }
+                return true;
+            }
+            return false;
+        }
+
+        /** Trim all strings, using String.trim().
+         *  Remove empty strings.
+         *  Normalize CharSequences to Strings.
+         */
+        public void trimText() {
+            checkNotFrozen();
+            int fillp = 0;
+            int size = this.size;
+            Object[] parts = this.parts;
+            for (int i = 0; i < size; i++) {
+                Object e = parts[i];
+                if (e instanceof CharSequence) {
+                    String tt = e.toString().trim();
+                    if (tt.length() == 0) {
+                        continue;
+                    }
+                    e = tt;
+                }
+                parts[fillp++] = e;
+            }
+            while (size > fillp) {
+                parts[--size] = null;
+            }
+            this.size = fillp;
+        }
+
+        /** Add one or more subelements at the given position.
+         *  If the object reference is null, nothing happens.
+         *  If the object is an anonymous Element, addAll is called.
+         *  If the object is a TokenList, addAll is called (to add the tokens).
+         *  Otherwise, add is called, adding a single subelement or string.
+         *  The net effect is to add zero or more tokens.
+         *  The returned value is the number of added elements.
+         *  <p>
+         *  Note that getText() can return a TokenList which preserves
+         *  token boundaries in the text source.  Such a text will be
+         *  added as multiple text sub-elements.
+         *  <p>
+         *  If a text string is added adjacent to an immediately
+         *  preceding string, there will be a token boundary between
+         *  the strings, which will print as an extra space.
+         */
+        public int addContent(int i, Object e) {
+            if (e == null) {
+                return 0;
+            } else if (e instanceof TokenList) {
+                return addAll(i, (Collection) e);
+            } else if (e instanceof Element
+                    && ((Element) e).isAnonymous()) {
+                return addAll(i, (Element) e);
+            } else {
+                add(i, e);
+                return 1;
+            }
+        }
+
+        public int addContent(Object e) {
+            return addContent(size, e);
+        }
+
+        public Object[] toArray() {
+            Object[] result = new Object[size];
+            System.arraycopy(parts, 0, result, 0, size);
+            return result;
+        }
+
+        public Element copyContentOnly() {
+            Element content = new Element(size);
+            System.arraycopy(parts, 0, content.parts, 0, size);
+            content.size = size;
+            return content;
+        }
+
+        public void sort(Comparator<Object> c) {
+            Arrays.sort(parts, 0, size, c);
+        }
+
+        public void sort() {
+            sort(CONTENT_ORDER);
+        }
+
+        /** Equivalent to Collections.reverse(this.asList()). */
+        public void reverse() {
+            for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) {
+                Object p = parts[i];
+                parts[i] = parts[j];
+                parts[j] = p;
+            }
+        }
+
+        /** Equivalent to Collections.shuffle(this.asList() [, rnd]). */
+        public void shuffle() {
+            Collections.shuffle(this.asList());
+        }
+
+        public void shuffle(Random rnd) {
+            Collections.shuffle(this.asList(), rnd);
+        }
+
+        /** Equivalent to Collections.rotate(this.asList(), dist). */
+        public void rotate(int dist) {
+            Collections.rotate(this.asList(), dist);
+        }
+
+        /** Equivalent to Collections.min(this.asList(), c). */
+        public Object min(Comparator<Object> c) {
+            return Collections.min(this.asList(), c);
+        }
+
+        public Object min() {
+            return min(CONTENT_ORDER);
+        }
+
+        /** Equivalent to Collections.max(this.asList(), c). */
+        public Object max(Comparator<Object> c) {
+            return Collections.max(this.asList(), c);
+        }
+
+        public Object max() {
+            return max(CONTENT_ORDER);
+        }
+
+        public int addAll(int i, Collection c) {
+            if (c instanceof LView) {
+                return addAll(i, ((LView) c).asElement());
+            } else {
+                int csize = c.size();
+                if (csize == 0) {
+                    return 0;
+                }
+                openOrExpand(i, csize);
+                int fill = i;
+                for (Object part : c) {
+                    parts[fill++] = part;
+                }
+                return csize;
+            }
+        }
+
+        public int addAll(int i, Element e) {
+            int esize = e.size;
+            if (esize == 0) {
+                return 0;
+            }
+            openOrExpand(i, esize);
+            System.arraycopy(e.parts, 0, parts, i, esize);
+            return esize;
+        }
+
+        public int addAll(Collection c) {
+            return addAll(size, c);
+        }
+
+        public int addAll(Element e) {
+            return addAll(size, e);
+        }
+
+        public int addAllAttrsFrom(Element e) {
+            int added = 0;
+            for (int k = 0; e.containsAttr(k); k++) {
+                String old = setAttr(e.getAttrName(k), e.getAttr(k));
+                if (old == null) {
+                    added += 1;
+                }
+            }
+            // Return number of added (not merely changed) attrs.
+            return added;
+        }
+
+        // Search.
+        public boolean matches(Filter f) {
+            return f.filter(this) != null;
+        }
+
+        public Object find(Filter f) {
+            return findOrRemove(f, 0, false);
+        }
+
+        public Object find(Filter f, int fromIndex) {
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+            return findOrRemove(f, fromIndex, false);
+        }
+
+        /** Find the last element matching the given filter.
+         *  Return the filtered value.
+         */
+        public Object findLast(Filter f) {
+            return findOrRemoveLast(f, size - 1, false);
+        }
+
+        public Object findLast(Filter f, int fromIndex) {
+            if (fromIndex >= size) {
+                fromIndex = size - 1;
+            }
+            return findOrRemoveLast(f, fromIndex, false);
+        }
+
+        /** Find all elements matching the given filter.
+         *  If there is a non-null collection given as a sink,
+         *  transfer matching elements to the given collection.
+         *  The int result is the number of matching elements.
+         *  If there is a null sink given, the matching elements are
+         *  not collected.  If there is no sink given, the matching
+         *  elements are returned in an anonymous container element.
+         *  In no case is the receiver element changed.
+         *  <p>
+         *  Note that a simple count of matching elements can be
+         *  obtained by passing a null collection argument.
+         */
+        public Element findAll(Filter f) {
+            Element result = new Element();
+            findOrRemoveAll(f, false, 0, size, result.asList(), false);
+            return result;
+        }
+
+        public Element findAll(Filter f, int fromIndex, int toIndex) {
+            Element result = new Element(name);
+            findOrRemoveAll(f, false, fromIndex, toIndex, result.asList(), false);
+            return result;
+        }
+
+        public int findAll(Filter f, Collection<Object> sink) {
+            return findOrRemoveAll(f, false, 0, size, sink, false);
+        }
+
+        public int findAll(Filter f, int fromIndex, int toIndex, Collection<Object> sink) {
+            return findOrRemoveAll(f, false, fromIndex, toIndex, sink, false);
+        }
+
+        /// Driver routines.
+        private Object findOrRemove(Filter f, int fromIndex, boolean remove) {
+            for (int i = fromIndex; i < size; i++) {
+                Object x = f.filter(parts[i]);
+                if (x != null) {
+                    if (remove) {
+                        close(i, 1);
+                    }
+                    return x;
+                }
+            }
+            return null;
+        }
+
+        private Object findOrRemoveLast(Filter f, int fromIndex, boolean remove) {
+            for (int i = fromIndex; i >= 0; i--) {
+                Object x = f.filter(parts[i]);
+                if (x != null) {
+                    if (remove) {
+                        close(i, 1);
+                    }
+                    return x;
+                }
+            }
+            return null;
+        }
+
+        private int findOrRemoveAll(Filter f, boolean fInvert,
+                int fromIndex, int toIndex,
+                Collection<Object> sink, boolean remove) {
+            if (fromIndex < 0) {
+                badIndex(fromIndex);
+            }
+            if (toIndex > size) {
+                badIndex(toIndex);
+            }
+            int found = 0;
+            for (int i = fromIndex; i < toIndex; i++) {
+                Object p = parts[i];
+                Object x = f.filter(p);
+                if (fInvert ? (x == null) : (x != null)) {
+                    if (remove) {
+                        close(i--, 1);
+                        toIndex--;
+                    }
+                    found += XMLKit.addContent(fInvert ? p : x, sink);
+                }
+            }
+            return found;
+        }
+
+        public void replaceAll(Filter f) {
+            XMLKit.replaceAll(f, this.asList());
+        }
+
+        public void replaceAll(Filter f, int fromIndex, int toIndex) {
+            XMLKit.replaceAll(f, this.asList().subList(fromIndex, toIndex));
+        }
+
+        /// Recursive walks.
+        // findAllInTree(f)     == findAll(findInTree(f,S)), S.toElement
+        // findAllInTree(f,S)   == findAll(findInTree(content(f,S)))
+        // removeAllInTree(f)   == replaceAll(replaceInTree(and(f,emptyF)))
+        // removeAllInTree(f,S) == replaceAll(replaceInTree(and(content(f,S),emptyF)))
+        // retainAllInTree(f)   == removeAllInTree(not(f))
+        // replaceAllInTree(f)  == replaceAll(replaceInTree(f))
+        public Element findAllInTree(Filter f) {
+            Element result = new Element();
+            findAllInTree(f, result.asList());
+            return result;
+        }
+
+        public int findAllInTree(Filter f, Collection<Object> sink) {
+            int found = 0;
+            int size = this.size;  // cache copy
+            for (int i = 0; i < size; i++) {
+                Object p = parts[i];
+                Object x = f.filter(p);
+                if (x != null) {
+                    found += XMLKit.addContent(x, sink);
+                } else if (p instanceof Element) {
+                    found += ((Element) p).findAllInTree(f, sink);
+                }
+            }
+            return found;
+        }
+
+        public int countAllInTree(Filter f) {
+            return findAllInTree(f, null);
+        }
+
+        public int removeAllInTree(Filter f, Collection<Object> sink) {
+            if (sink == null) {
+                sink = newCounterColl();
+            }
+            replaceAll(replaceInTree(and(content(f, sink), emptyFilter())));
+            return sink.size();
+        }
+
+        public Element removeAllInTree(Filter f) {
+            Element result = new Element();
+            removeAllInTree(f, result.asList());
+            return result;
+        }
+
+        public int retainAllInTree(Filter f, Collection<Object> sink) {
+            return removeAllInTree(not(f), sink);
+        }
+
+        public Element retainAllInTree(Filter f) {
+            Element result = new Element();
+            retainAllInTree(f, result.asList());
+            return result;
+        }
+
+        public void replaceAllInTree(Filter f) {
+            replaceAll(replaceInTree(f));
+        }
+
+        /** Raise a ClassCastException if any subelements are the wrong type. */
+        public void checkPartsOnly(Class<?> elementClass) {
+            for (int i = 0; i < size; i++) {
+                elementClass.cast(parts[i]).getClass();
+            }
+        }
+
+        /** Return true if all sub-elements are of the given type. */
+        public boolean isPartsOnly(Class<?> elementClass) {
+            for (int i = 0; i < size; i++) {
+                if (!elementClass.isInstance(parts[i])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /** Provides an iterable view of this object as a series of elements.
+         *  All sub-elements of this Element must be of type Element.
+         *  A ClassCastException is raised if there are non-Element sub-elements.
+         */
+        public <T> Iterable<T> partsOnly(Class<T> elementClass) {
+            checkPartsOnly(elementClass);
+            return (Iterable<T>) (Iterable) this;
+        }
+
+        public Iterable<Element> elements() {
+            return partsOnly(Element.class);
+        }
+
+        /// Useful shorthands.
+        // Finding or removing elements w/o regard to their type or content.
+        public Element findElement() {
+            return (Element) find(elementFilter());
+        }
+
+        public Element findAllElements() {
+            return findAll(elementFilter());
+        }
+
+        public Element removeElement() {
+            return (Element) remove(elementFilter());
+        }
+
+        public Element removeAllElements() {
+            return (Element) removeAll(elementFilter());
+        }
+
+        // Finding or removing by element tag or selected attribute,
+        // as if by elementFilter(name) or attrFilter(name, value).
+        // Roughly akin to Common Lisp ASSOC.
+        public Element findElement(String name) {
+            return (Element) find(elementFilter(name));
+        }
+
+        public Element removeElement(String name) {
+            return (Element) remove(elementFilter(name));
+        }
+
+        public Element findWithAttr(String key) {
+            return (Element) find(attrFilter(name));
+        }
+
+        public Element findWithAttr(String key, String value) {
+            return (Element) find(attrFilter(name, value));
+        }
+
+        public Element removeWithAttr(String key) {
+            return (Element) remove(attrFilter(name));
+        }
+
+        public Element removeWithAttr(String key, String value) {
+            return (Element) remove(attrFilter(name, value));
+        }
+
+        public Element findAllElements(String name) {
+            return findAll(elementFilter(name));
+        }
+
+        public Element removeAllElements(String name) {
+            return removeAll(elementFilter(name));
+        }
+
+        public Element retainAllElements(String name) {
+            return retainAll(elementFilter(name));
+        }
+
+        public Element findAllWithAttr(String key) {
+            return findAll(attrFilter(key));
+        }
+
+        public Element removeAllWithAttr(String key) {
+            return removeAll(attrFilter(key));
+        }
+
+        public Element retainAllWithAttr(String key) {
+            return retainAll(attrFilter(key));
+        }
+
+        public Element findAllWithAttr(String key, String value) {
+            return findAll(attrFilter(key, value));
+        }
+
+        public Element removeAllWithAttr(String key, String value) {
+            return removeAll(attrFilter(key, value));
+        }
+
+        public Element retainAllWithAttr(String key, String value) {
+            return retainAll(attrFilter(key, value));
+        }
+
+        public int countAll(Filter f) {
+            return findAll(f, null);
+        }
+
+        public int countAllElements() {
+            return countAll(elementFilter());
+        }
+
+        public int countAllElements(String name) {
+            return countAll(elementFilter(name));
+        }
+
+        public int countAllWithAttr(String key) {
+            return countAll(attrFilter(name));
+        }
+
+        public int countAllWithAttr(String key, String value) {
+            return countAll(attrFilter(key, value));
+        }
+
+        public int indexOf(Object e) {
+            for (int i = 0; i < size; i++) {
+                if (e.equals(parts[i])) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        public int lastIndexOf(Object e) {
+            for (int i = size - 1; i >= 0; i--) {
+                if (e.equals(parts[i])) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        /** Remove the first element matching the given filter.
+         *  Return the filtered value.
+         */
+        public int indexOf(Filter f) {
+            return indexOf(f, 0);
+        }
+
+        public int indexOf(Filter f, int fromIndex) {
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+            for (int i = fromIndex; i < size; i++) {
+                Object x = f.filter(parts[i]);
+                if (x != null) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        /** Remove the last element matching the given filter.
+         *  Return the filtered value.
+         */
+        public int lastIndexOf(Filter f) {
+            return lastIndexOf(f, size - 1);
+        }
+
+        public int lastIndexOf(Filter f, int fromIndex) {
+            if (fromIndex >= size) {
+                fromIndex = size - 1;
+            }
+            for (int i = fromIndex; i >= 0; i--) {
+                Object x = f.filter(parts[i]);
+                if (x != null) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        public boolean contains(Object e) {
+            return indexOf(e) >= 0;
+        }
+
+        // attributes
+        private int findOrCreateAttr(String key, boolean create) {
+            key.toString();  // null check
+            int attrBase = parts.length;
+            for (int i = parts.length - 2; i >= size; i -= 2) {
+                String akey = (String) parts[i + 0];
+                if (akey == null) {
+                    if (!create) {
+                        return -1;
+                    }
+                    if (i == size) {
+                        break;  // NEED_SLOP
+                    }
+                    parts[i + 0] = key;
+                    //parts[i+1] = ""; //caller responsibility
+                    return i;
+                }
+                attrBase = i;
+                if (akey.equals(key)) {
+                    return i;
+                }
+            }
+            // If we fell through, we ran into an element part.
+            // Therefore we have run out of empty slots.
+            if (!create) {
+                return -1;
+            }
+            assert (!isFrozen());
+            int alen = parts.length - attrBase;
+            expand(size, 2); // generally expands by more than 2
+            // since there was a reallocation, the garbage slots are really null
+            assert (parts[size + 0] == null && parts[size + 1] == null);
+            alen += 2;
+            int i = parts.length - alen;
+            parts[i + 0] = key;
+            //parts[i+1] = ""; //caller responsibility
+            return i;
+        }
+
+        public int attrSize() {
+            return attrLength() >>> 1;
+        }
+
+        public int indexOfAttr(String key) {
+            return findOrCreateAttr(key, false);
+        }
+
+        public boolean containsAttr(String key) {
+            return indexOfAttr(key) >= 0;
+        }
+
+        public String getAttr(String key) {
+            return getAttr(key, null);
+        }
+
+        public String getAttr(String key, String dflt) {
+            int i = findOrCreateAttr(key, false);
+            return (i < 0) ? dflt : (String) parts[i + 1];
+        }
+
+        public TokenList getAttrList(String key) {
+            return convertToList(getAttr(key));
+        }
+
+        public Number getAttrNumber(String key) {
+            return convertToNumber(getAttr(key));
+        }
+
+        public long getAttrLong(String key) {
+            return getAttrLong(key, 0);
+        }
+
+        public double getAttrDouble(String key) {
+            return getAttrDouble(key, 0.0);
+        }
+
+        public long getAttrLong(String key, long dflt) {
+            return convertToLong(getAttr(key), dflt);
+        }
+
+        public double getAttrDouble(String key, double dflt) {
+            return convertToDouble(getAttr(key), dflt);
+        }
+
+        int indexAttr(int k) {
+            int i = parts.length - (k * 2) - 2;
+            if (i < size || parts[i] == null) {
+                return -2;  // always oob
+            }
+            return i;
+        }
+
+        public boolean containsAttr(int k) {
+            return indexAttr(k) >= 0;
+        }
+
+        public String getAttr(int k) {
+            return (String) parts[indexAttr(k) + 1];
+        }
+
+        public String getAttrName(int k) {
+            return (String) parts[indexAttr(k) + 0];
+        }
+
+        public Iterable<String> attrNames() {
+            //return asAttrMap().keySet();
+            return new Iterable<String>() {
+
+                public Iterator<String> iterator() {
+                    return new ANItr();
+                }
+            };
+        }
+
+        // Hand-inlined replacement for asAttrMap().keySet().iterator():
+        class ANItr implements Iterator<String> {
+
+            boolean lastRet;
+            int cursor = -2;  // pointer from end of parts
+
+            public boolean hasNext() {
+                int i = cursor + parts.length;
+                return i >= size && parts[i] == null;
+            }
+
+            public String next() {
+                int i = cursor + parts.length;
+                Object x;
+                if (i < size || (x = parts[i]) == null) {
+                    nsee();
+                    return null;
+                }
+                cursor -= 2;
+                lastRet = true;
+                return (String) x;
+            }
+
+            public void remove() {
+                if (!lastRet) {
+                    throw new IllegalStateException();
+                }
+                Element.this.removeAttr((-4 - cursor) / 2);
+                cursor += 2;
+                lastRet = false;
+            }
+
+            Exception nsee() {
+                throw new NoSuchElementException("attribute " + (-2 - cursor) / 2);
+            }
+        }
+
+        /** Return an anonymous copy of self, but only with attributes.
+         */
+        public Element copyAttrsOnly() {
+            int alen = attrLength();
+            Element attrs = new Element(alen);
+            Object[] attrParts = attrs.parts;
+            assert (attrParts.length == NEED_SLOP + alen);
+            System.arraycopy(parts, parts.length - alen,
+                    attrParts, NEED_SLOP,
+                    alen);
+            return attrs;
+        }
+
+        /** Get all attributes, represented as an element with sub-elements.
+         *  The name of each sub-element is the attribute key, and the text
+         *  This is a fresh copy, and can be updated with affecting the original.
+         *  of each sub-element is the corresponding attribute value.
+         *  See also asAttrMap() for a "live" view of all the attributes as a Map.
+         */
+        public Element getAttrs() {
+            int asize = attrSize();
+            Element attrs = new Element(ANON_NAME, asize, NEED_SLOP + asize);
+            for (int i = 0; i < asize; i++) {
+                Element attr = new Element(getAttrName(i), 1, NEED_SLOP + 1);
+                // %%% normalize attrs to token lists?
+                attr.setRaw(0, getAttr(i));
+                attrs.setRaw(i, attr);
+            }
+            return attrs;
+        }
+
+        public void setAttrs(Element attrs) {
+            int alen = attrLength();
+            clearParts(parts.length - alen, alen);
+            if (!hasNulls(NEED_SLOP + attrs.size * 2)) {
+                expand(size, attrs.size * 2);
+            }
+            addAttrs(attrs);
+        }
+
+        public void addAttrs(Element attrs) {
+            for (int i = 0; i < attrs.size; i++) {
+                Element attr = (Element) attrs.get(i);
+                setAttr(attr.name, attr.getText().toString());
+            }
+        }
+
+        public void removeAttr(int i) {
+            checkNotFrozen();
+            while ((i -= 2) >= size) {
+                Object k = parts[i + 0];
+                Object v = parts[i + 1];
+                if (k == null) {
+                    break;
+                }
+                parts[i + 2] = k;
+                parts[i + 3] = v;
+            }
+            parts[i + 2] = null;
+            parts[i + 3] = null;
+        }
+
+        public void clearAttrs() {
+            if (parts.length == 0 || parts[parts.length - 1] == null) {
+                return;  // no attrs to clear
+            }
+            checkNotFrozen();
+            if (size == 0) {
+                // If no elements, free the parts array.
+                parts = noPartsNotFrozen;
+                return;
+            }
+            for (int i = parts.length - 1; parts[i] != null; i--) {
+                assert (i >= size);
+                parts[i] = null;
+            }
+        }
+
+        public String setAttr(String key, String value) {
+            String old;
+            if (value == null) {
+                int i = findOrCreateAttr(key, false);
+                if (i >= 0) {
+                    old = (String) parts[i + 1];
+                    removeAttr(i);
+                } else {
+                    old = null;
+                }
+            } else {
+                checkNotFrozen();
+                int i = findOrCreateAttr(key, true);
+                old = (String) parts[i + 1];
+                parts[i + 1] = value;
+            }
+            return old;
+        }
+
+        public String setAttrList(String key, List<String> l) {
+            if (l == null) {
+                return setAttr(key, null);
+            }
+            if (!(l instanceof TokenList)) {
+                l = new TokenList(l);
+            }
+            return setAttr(key, l.toString());
+        }
+
+        public String setAttrNumber(String key, Number n) {
+            return setAttr(key, (n == null) ? null : n.toString());
+        }
+
+        public String setAttrLong(String key, long n) {
+            return setAttr(key, (n == 0) ? null : String.valueOf(n));
+        }
+
+        public String setAttrDouble(String key, double n) {
+            return setAttr(key, (n == 0) ? null : String.valueOf(n));
+        }
+
+        public String setAttr(int k, String value) {
+            int i = indexAttr(k);
+            String old = (String) parts[i + 1];
+            if (value == null) {
+                removeAttr(i);
+            } else {
+                checkNotFrozen();
+                parts[i + 1] = value;
+            }
+            return old;
+        }
+
+        int attrLength() {
+            return parts.length - attrBase();
+        }
+
+        /** Are the attributes of the two two elements equal?
+         *  Disregards name, sub-elements, and ordering of attributes.
+         */
+        public boolean equalAttrs(Element that) {
+            int alen = this.attrLength();
+            if (alen != that.attrLength()) {
+                return false;
+            }
+            if (alen == 0) {
+                return true;
+            }
+            return compareAttrs(alen, that, alen, false) == 0;
+        }
+
+        private int compareAttrs(int thisAlen,
+                Element that, int thatAlen,
+                boolean fullCompare) {
+            Object[] thisParts = this.parts;
+            Object[] thatParts = that.parts;
+            int thisBase = thisParts.length - thisAlen;
+            int thatBase = thatParts.length - thatAlen;
+            // search indexes into unmatched parts of this.attrs:
+            int firstI = 0;
+            // search indexes into unmatched parts of that.attrs:
+            int firstJ = 0;
+            int lastJ = thatAlen - 2;
+            // try to find the mismatch with the first key:
+            String firstKey = null;
+            int firstKeyValCmp = 0;
+            int foundKeys = 0;
+            for (int i = 0; i < thisAlen; i += 2) {
+                String key = (String) thisParts[thisBase + i + 0];
+                String val = (String) thisParts[thisBase + i + 1];
+                String otherVal = null;
+                for (int j = firstJ; j <= lastJ; j += 2) {
+                    if (key.equals(thatParts[thatBase + j + 0])) {
+                        foundKeys += 1;
+                        otherVal = (String) thatParts[thatBase + j + 1];
+                        // Optimization:  Narrow subsequent searches when easy.
+                        if (j == lastJ) {
+                            lastJ -= 2;
+                        } else if (j == firstJ) {
+                            firstJ += 2;
+                        }
+                        if (i == firstI) {
+                            firstI += 2;
+                        }
+                        break;
+                    }
+                }
+                int valCmp;
+                if (otherVal != null) {
+                    // The key was found.
+                    if (!fullCompare) {
+                        if (!val.equals(otherVal)) {
+                            return 1 - 0; //arb.
+                        }
+                        continue;
+                    }
+                    valCmp = val.compareTo(otherVal);
+                } else {
+                    // Found the key in this but not that.
+                    // Such a mismatch puts the guy missing the key last.
+                    valCmp = 0 - 1;
+                }
+                if (valCmp != 0) {
+                    // found a mismatch, key present in both elems
+                    if (firstKey == null
+                            || firstKey.compareTo(key) > 0) {
+                        // found a better key
+                        firstKey = key;
+                        firstKeyValCmp = valCmp;
+                    }
+                }
+            }
+            // We have located the first mismatch of all keys in this.attrs.
+            // In general we must also look for keys in that.attrs but missing
+            // from this.attrs; such missing keys, if earlier than firstKey,
+            // rule the comparison.
+
+            // We can sometimes prove quickly there is no missing key.
+            if (foundKeys == thatAlen / 2) {
+                // Exhausted all keys in that.attrs.
+                return firstKeyValCmp;
+            }
+
+            // Search for a missing key in that.attrs earlier than firstKey.
+            findMissingKey:
+            for (int j = firstJ; j <= lastJ; j += 2) {
+                String otherKey = (String) thatParts[thatBase + j + 0];
+                if (firstKey == null
+                        || firstKey.compareTo(otherKey) > 0) {
+                    // Found a better key; is it missing?
+                    for (int i = firstI; i < thisAlen; i += 2) {
+                        if (otherKey.equals(thisParts[thisBase + i + 0])) {
+                            continue findMissingKey;
+                        }
+                    }
+                    // If we get here, there was no match in this.attrs.
+                    return 1 - 0;
+                }
+            }
+
+            // No missing key.  Previous comparison value rules.
+            return firstKeyValCmp;
+        }
+
+        // Binary search looking for first non-null after size.
+        int attrBase() {
+            // Smallest & largest possible attribute indexes:
+            int kmin = 0;
+            int kmax = (parts.length - size) >>> 1;
+            // earlist possible attribute position:
+            int abase = parts.length - (kmax * 2);
+            // binary search using scaled indexes:
+            while (kmin != kmax) {
+                int kmid = kmin + ((kmax - kmin) >>> 1);
+                if (parts[abase + (kmid * 2)] == null) {
+                    kmin = kmid + 1;
+                } else {
+                    kmax = kmid;
+                }
+                assert (kmin <= kmax);
+            }
+            return abase + (kmax * 2);
+        }
+
+        /** Sort attributes by name. */
+        public void sortAttrs() {
+            checkNotFrozen();
+            int abase = attrBase();
+            int alen = parts.length - abase;
+            String[] buf = new String[alen];
+            // collect keys
+            for (int k = 0; k < alen / 2; k++) {
+                String akey = (String) parts[abase + (k * 2) + 0];
+                buf[k] = akey;
+            }
+            Arrays.sort(buf, 0, alen / 2);
+            // collect values
+            for (int k = 0; k < alen / 2; k++) {
+                String akey = buf[k];
+                buf[k + alen / 2] = getAttr(akey);
+            }
+            // reorder keys and values
+            int fillp = parts.length;
+            for (int k = 0; k < alen / 2; k++) {
+                String akey = buf[k];
+                String aval = buf[k + alen / 2];
+                fillp -= 2;
+                parts[fillp + 0] = akey;
+                parts[fillp + 1] = aval;
+            }
+            assert (fillp == abase);
+        }
+
+        /*
+        Notes on whitespace and tokenization.
+        On input, never split CDATA blocks.  They remain single tokens.
+        ?Try to treat encoded characters as CDATA-quoted, also?
+
+        Internally, each String sub-element is logically a token.
+        However, if there was no token-splitting on input,
+        consecutive strings are merged by the parser.
+
+        Internally, we need addToken (intervening blank) and addText
+        (hard concatenation).
+
+        Optionally on input, tokenize unquoted text into words.
+        Between each adjacent word pair, elide either one space
+        or all space.
+
+        On output, we always add spaces between tokens.
+        The Element("a", {"b", "c", Element("d"), "e    f"})
+        outputs as "<a>b c<d/>e    f</a>"
+         */
+        /** Split strings into tokens, using a StringTokenizer. */
+        public void tokenize(String delims, boolean returnDelims) {
+            checkNotFrozen();
+            if (delims == null) {
+                delims = WHITESPACE_CHARS;  // StringTokenizer default
+            }
+            for (int i = 0; i < size; i++) {
+                if (!(parts[i] instanceof CharSequence)) {
+                    continue;
+                }
+                int osize = size;
+                String str = parts[i].toString();
+                StringTokenizer st = new StringTokenizer(str, delims, returnDelims);
+                int nstrs = st.countTokens();
+                switch (nstrs) {
+                    case 0:
+                        close(i--, 1);
+                        break;
+                    case 1:
+                        parts[i] = st.nextToken();
+                        break;
+                    default:
+                        openOrExpand(i + 1, nstrs - 1);
+                        for (int j = 0; j < nstrs; j++) {
+                            parts[i + j] = st.nextToken();
+                        }
+                        i += nstrs - 1;
+                        break;
+                }
+            }
+        }
+
+        public void tokenize(String delims) {
+            tokenize(delims, false);
+        }
+
+        public void tokenize() {
+            tokenize(null, false);
+        }
+
+        // views
+        class LView extends AbstractList<Object> {
+
+            Element asElement() {
+                return Element.this;
+            }
+
+            public int size() {
+                return Element.this.size();
+            }
+
+            public Object get(int i) {
+                return Element.this.get(i);
+            }
+
+            @Override
+            public boolean contains(Object e) {
+                return Element.this.contains(e);
+            }
+
+            @Override
+            public Object[] toArray() {
+                return Element.this.toArray();
+            }
+
+            @Override
+            public int indexOf(Object e) {
+                return Element.this.indexOf(e);
+            }
+
+            @Override
+            public int lastIndexOf(Object e) {
+                return Element.this.lastIndexOf(e);
+            }
+
+            @Override
+            public void add(int i, Object e) {
+                ++modCount;
+                Element.this.add(i, e);
+            }
+
+            @Override
+            public boolean addAll(int i, Collection<? extends Object> c) {
+                ++modCount;
+                return Element.this.addAll(i, c) > 0;
+            }
+
+            @Override
+            public boolean addAll(Collection<? extends Object> c) {
+                ++modCount;
+                return Element.this.addAll(c) > 0;
+            }
+
+            @Override
+            public Object remove(int i) {
+                ++modCount;
+                return Element.this.remove(i);
+            }
+
+            @Override
+            public Object set(int i, Object e) {
+                ++modCount;
+                return Element.this.set(i, e);
+            }
+
+            @Override
+            public void clear() {
+                ++modCount;
+                Element.this.clear();
+            }
+            // Others: toArray(Object[]), containsAll, removeAll, retainAll
+        }
+
+        /** Produce a list view of sub-elements.
+         *  (The list view does not provide access to the element's
+         *  name or attributes.)
+         *  Changes to this view are immediately reflected in the
+         *  element itself.
+         */
+        public List<Object> asList() {
+            return new LView();
+        }
+
+        /** Produce a list iterator on all sub-elements. */
+        public ListIterator<Object> iterator() {
+            //return asList().listIterator();
+            return new Itr();
+        }
+
+        // Hand-inlined replacement for LView.listIterator():
+        class Itr implements ListIterator<Object> {
+
+            int lastRet = -1;
+            int cursor = 0;
+
+            public boolean hasNext() {
+                return cursor < size;
+            }
+
+            public boolean hasPrevious() {
+                return cursor > 0 && cursor <= size;
+            }
+
+            public Object next() {
+                if (!hasNext()) {
+                    nsee();
+                }
+                return parts[lastRet = cursor++];
+            }
+
+            public Object previous() {
+                if (!hasPrevious()) {
+                    nsee();
+                }
+                return parts[--cursor];
+            }
+
+            public int nextIndex() {
+                return cursor;
+            }
+
+            public int previousIndex() {
+                return cursor - 1;
+            }
+
+            public void set(Object x) {
+                parts[lastRet] = x;
+            }
+
+            public void add(Object x) {
+                lastRet = -1;
+                Element.this.add(cursor++, x);
+            }
+
+            public void remove() {
+                if (lastRet < 0) {
+                    throw new IllegalStateException();
+                }
+                Element.this.remove(lastRet);
+                if (lastRet < cursor) {
+                    --cursor;
+                }
+                lastRet = -1;
+            }
+
+            void nsee() {
+                throw new NoSuchElementException("element " + cursor);
+            }
+        }
+
+        /** A PrintWriter which always appends as if by addText.
+         *  Use of this stream may insert a StringBuffer at the end
+         *  of the Element.  The user must not directly modify this
+         *  StringBuffer, or use it in other data structures.
+         *  From time to time, the StringBuffer may be replaced by a
+         *  constant string as a result of using the PrintWriter.
+         */
+        public PrintWriter asWriter() {
+            return new ElemW();
+        }
+
+        class ElemW extends PrintWriter {
+
+            ElemW() {
+                super(new StringWriter());
+            }
+            final StringBuffer buf = ((StringWriter) out).getBuffer();
+
+            {
+                lock = buf;
+            }  // synchronize on this buffer
+
+            @Override
+            public void println() {
+                synchronized (buf) {
+                    ensureCursor();
+                    super.println();
+                }
+            }
+
+            @Override
+            public void write(int ch) {
+                synchronized (buf) {
+                    ensureCursor();
+                    //buf.append(ch);
+                    super.write(ch);
+                }
+            }
+
+            @Override
+            public void write(char buf[], int off, int len) {
+                synchronized (buf) {
+                    ensureCursor();
+                    super.write(buf, off, len);
+                }
+            }
+
+            @Override
+            public void write(String s, int off, int len) {
+                synchronized (buf) {
+                    ensureCursor();
+                    //buf.append(s.substring(off, off+len));
+                    super.write(s, off, len);
+                }
+            }
+
+            @Override
+            public void write(String s) {
+                synchronized (buf) {
+                    ensureCursor();
+                    //buf.append(s);
+                    super.write(s);
+                }
+            }
+
+            private void ensureCursor() {
+                checkNotFrozen();
+                if (getLast() != buf) {
+                    int pos = indexOf(buf);
+                    if (pos >= 0) {
+                        // Freeze the pre-existing use of buf.
+                        setRaw(pos, buf.toString());
+                    }
+                    add(buf);
+                }
+            }
+        }
+
+        /** Produce a map view of attributes, in which the attribute
+         *  name strings are the keys.
+         *  (The map view does not provide access to the element's
+         *  name or sub-elements.)
+         *  Changes to this view are immediately reflected in the
+         *  element itself.
+         */
+        public Map<String, String> asAttrMap() {
+            class Entry implements Map.Entry<String, String> {
+
+                final int k;
+
+                Entry(int k) {
+                    this.k = k;
+                    assert (((String) getKey()).toString() != null);  // check, fail-fast
+                }
+
+                public String getKey() {
+                    return Element.this.getAttrName(k);
+                }
+
+                public String getValue() {
+                    return Element.this.getAttr(k);
+                }
+
+                public String setValue(String v) {
+                    return Element.this.setAttr(k, v.toString());
+                }
+
+                @Override
+                public boolean equals(Object o) {
+                    if (!(o instanceof Map.Entry)) {
+                        return false;
+                    }
+                    Map.Entry that = (Map.Entry) o;
+                    return (this.getKey().equals(that.getKey())
+                            && this.getValue().equals(that.getValue()));
+                }
+
+                @Override
+                public int hashCode() {
+                    return getKey().hashCode() ^ getValue().hashCode();
+                }
+            }
+            class EIter implements Iterator<Map.Entry<String, String>> {
+
+                int k = 0;  // index of pending next() attribute
+
+                public boolean hasNext() {
+                    return Element.this.containsAttr(k);
+                }
+
+                public Map.Entry<String, String> next() {
+                    return new Entry(k++);
+                }
+
+                public void remove() {
+                    Element.this.removeAttr(--k);
+                }
+            }
+            class ESet extends AbstractSet<Map.Entry<String, String>> {
+
+                public int size() {
+                    return Element.this.attrSize();
+                }
+
+                public Iterator<Map.Entry<String, String>> iterator() {
+                    return new EIter();
+                }
+
+                @Override
+                public void clear() {
+                    Element.this.clearAttrs();
+                }
+            }
+            class AView extends AbstractMap<String, String> {
+
+                private transient Set<Map.Entry<String, String>> eSet;
+
+                public Set<Map.Entry<String, String>> entrySet() {
+                    if (eSet == null) {
+                        eSet = new ESet();
+                    }
+                    return eSet;
+                }
+
+                @Override
+                public int size() {
+                    return Element.this.attrSize();
+                }
+
+                public boolean containsKey(String k) {
+                    return Element.this.containsAttr(k);
+                }
+
+                public String get(String k) {
+                    return Element.this.getAttr(k);
+                }
+
+                @Override
+                public String put(String k, String v) {
+                    return Element.this.setAttr(k, v.toString());
+                }
+
+                public String remove(String k) {
+                    return Element.this.setAttr(k, null);
+                }
+            }
+            return new AView();
+        }
+
+        /** Reports number of additional elements this object can accommodate
+         *  without reallocation.
+         */
+        public int getExtraCapacity() {
+            int abase = attrBase();
+            return Math.max(0, abase - size - NEED_SLOP);
+        }
+
+        /** Ensures that at least the given number of additional elements
+         *  can be added to this object without reallocation.
+         */
+        public void ensureExtraCapacity(int cap) {
+            if (cap == 0 || hasNulls(cap + NEED_SLOP)) {
+                return;
+            }
+            setExtraCapacity(cap);
+        }
+
+        /**
+         * Trim excess capacity to zero, or do nothing if frozen.
+         * This minimizes the space occupied by this Element,
+         * at the expense of a reallocation if sub-elements or attributes
+         * are added later.
+         */
+        public void trimToSize() {
+            if (isFrozen()) {
+                return;
+            }
+            setExtraCapacity(0);
+        }
+
+        /** Changes the number of additional elements this object can accommodate
+         *  without reallocation.
+         */
+        public void setExtraCapacity(int cap) {
+            checkNotFrozen();
+            int abase = attrBase();
+            int alen = parts.length - abase;  // slots allocated for attrs
+            int nlen = size + cap + NEED_SLOP + alen;
+            if (nlen != parts.length) {
+                Object[] nparts = new Object[nlen];
+                // copy attributes
+                System.arraycopy(parts, abase, nparts, nlen - alen, alen);
+                // copy sub-elements
+                System.arraycopy(parts, 0, nparts, 0, size);
+                parts = nparts;
+            }
+            assert (cap == getExtraCapacity());
+        }
+
+        // Return true if there are at least len nulls of slop available.
+        boolean hasNulls(int len) {
+            if (len == 0) {
+                return true;
+            }
+            int lastNull = size + len - 1;
+            if (lastNull >= parts.length) {
+                return false;
+            }
+            return (parts[lastNull] == null);
+        }
+
+        // Opens up parts array at pos by len spaces.
+        void open(int pos, int len) {
+            assert (pos < size);
+            assert (hasNulls(len + NEED_SLOP));
+            checkNotFrozen();
+            int nsize = size + len;
+            int tlen = size - pos;
+            System.arraycopy(parts, pos, parts, pos + len, tlen);
+            size = nsize;
+        }
+
+        // Reallocate and open up at parts[pos] to at least len empty places.
+        // Shift anything after pos right by len.  Reallocate if necessary.
+        // If pos < size, caller must fill it in with non-null values.
+        // Returns incremented size; caller is responsible for storing it
+        // down, if desired.
+        int expand(int pos, int len) {
+            assert (pos <= size);
+            // There must be at least len nulls between elems and attrs.
+            assert (!hasNulls(NEED_SLOP + len));  // caller responsibility
+            checkNotFrozen();
+            int nsize = size + len;  // length of all elements
+            int tlen = size - pos;   // length of elements in post-pos tail
+            int abase = attrBase();
+            int alen = parts.length - abase;  // slots allocated for attrs
+            int nlen = nsize + alen + NEED_SLOP;
+            nlen += (nlen >>> 1);  // add new slop!
+            Object[] nparts = new Object[nlen];
+            // copy head of sub-elements
+            System.arraycopy(parts, 0, nparts, 0, pos);
+            // copy tail of sub-elements
+            System.arraycopy(parts, pos, nparts, pos + len, tlen);
+            // copy attributes
+            System.arraycopy(parts, abase, nparts, nlen - alen, alen);
+            // update self
+            parts = nparts;
+            //assert(hasNulls(len));  <- not yet true, since size != nsize
+            return nsize;
+        }
+
+        // Open or expand at the given position, as appropriate.
+        boolean openOrExpand(int pos, int len) {
+            if (pos < 0 || pos > size) {
+                badIndex(pos);
+            }
+            if (hasNulls(len + NEED_SLOP)) {
+                if (pos == size) {
+                    size += len;
+                } else {
+                    open(pos, len);
+                }
+                return false;
+            } else {
+                size = expand(pos, len);
+                return true;
+            }
+        }
+
+        // Close up at parts[pos] len old places.
+        // Shift anything after pos left by len.
+        // Fill unused end of parts with null.
+        void close(int pos, int len) {
+            assert (len > 0);
+            assert ((size - pos) >= len);
+            checkNotFrozen();
+            int tlen = (size - pos) - len;   // length of elements in post-pos tail
+            int nsize = size - len;
+            System.arraycopy(parts, pos + len, parts, pos, tlen);
+            // reinitialize the unoccupied slots to null
+            clearParts(nsize, nsize + len);
+            // update self
+            size = nsize;
+            assert (hasNulls(len));
+        }
+
+        public void writeTo(Writer w) throws IOException {
+            new Printer(w).print(this);
+        }
+
+        public void writePrettyTo(Writer w) throws IOException {
+            prettyPrintTo(w, this);
+        }
+
+        public String prettyString() {
+            StringWriter sw = new StringWriter();
+            try {
+                writePrettyTo(sw);
+            } catch (IOException ee) {
+                throw new Error(ee);  // should not happen
+            }
+            return sw.toString();
+        }
+
+        @Override
+        public String toString() {
+            StringWriter sw = new StringWriter();
+            try {
+                writeTo(sw);
+            } catch (IOException ee) {
+                throw new Error(ee);  // should not happen
+            }
+            return sw.toString();
+        }
+
+        public String dump() {
+            // For debugging only.  Reveals internal layout.
+            StringBuilder buf = new StringBuilder();
+            buf.append("<").append(name).append("[").append(size).append("]");
+            for (int i = 0; i < parts.length; i++) {
+                Object p = parts[i];
+                if (p == null) {
+                    buf.append(" null");
+                } else {
+                    buf.append(" {");
+                    String cname = p.getClass().getName();
+                    cname = cname.substring(1 + cname.indexOf('/'));
+                    cname = cname.substring(1 + cname.indexOf('$'));
+                    cname = cname.substring(1 + cname.indexOf('#'));
+                    if (!cname.equals("String")) {
+                        buf.append(cname).append(":");
+                    }
+                    buf.append(p);
+                    buf.append("}");
+                }
+            }
+            return buf.append(">").toString();
+        }
+
+        public static java.lang.reflect.Method method(String name) {
+            HashMap allM = allMethods;
+            if (allM == null) {
+                allM = makeAllMethods();
+            }
+            java.lang.reflect.Method res = (java.lang.reflect.Method) allMethods.get(name);
+            if (res == null) {
+                throw new IllegalArgumentException(name);
+            }
+            return res;
+        }
+        private static HashMap allMethods;
+
+        private static synchronized HashMap makeAllMethods() {
+            if (allMethods != null) {
+                return allMethods;
+            }
+            java.lang.reflect.Method[] methods = Element.class.getMethods();
+            HashMap<String, java.lang.reflect.Method> allM = new HashMap<String, java.lang.reflect.Method>(),
+                    ambig = new HashMap<String, java.lang.reflect.Method>();
+            for (int i = 0; i < methods.length; i++) {
+                java.lang.reflect.Method m = methods[i];
+                Class[] args = m.getParameterTypes();
+                String name = m.getName();
+                assert (java.lang.reflect.Modifier.isPublic(m.getModifiers()));
+                if (name.startsWith("notify")) {
+                    continue;
+                }
+                if (name.endsWith("Attr")
+                        && args.length > 0 && args[0] == int.class) // ignore getAttr(int), etc.
+                {
+                    continue;
+                }
+                if (name.endsWith("All")
+                        && args.length > 1 && args[0] == Filter.class) // ignore findAll(Filter, int...), etc.
+                {
+                    continue;
+                }
+                java.lang.reflect.Method pm = allM.put(name, m);
+                if (pm != null) {
+                    Class[] pargs = pm.getParameterTypes();
+                    if (pargs.length > args.length) {
+                        allM.put(name, pm);   // put it back
+                    } else if (pargs.length == args.length) {
+                        ambig.put(name, pm);  // make a note of it
+                    }
+                }
+            }
+            // Delete ambiguous methods.
+            for (Map.Entry<String, java.lang.reflect.Method> e : ambig.entrySet()) {
+                String name = e.getKey();
+                java.lang.reflect.Method pm = e.getValue();
+                java.lang.reflect.Method m = allM.get(name);
+                Class[] args = m.getParameterTypes();
+                Class[] pargs = pm.getParameterTypes();
+                if (pargs.length == args.length) {
+                    //System.out.println("ambig: "+pm);
+                    //System.out.println(" with: "+m);
+                    //ambig: int addAll(int,Element)
+                    // with: int addAll(int,Collection)
+                    allM.put(name, null);  // get rid of
+                }
+            }
+            //System.out.println("allM: "+allM);
+            return allMethods = allM;
+        }
+    }
+
+    static Object fixupString(Object part) {
+        if (part instanceof CharSequence && !(part instanceof String)) {
+            return part.toString();
+        } else {
+            return part;
+        }
+    }
+
+    public static final class Special implements Comparable<Special> {
+
+        String kind;
+        Object value;
+
+        public Special(String kind, Object value) {
+            this.kind = kind;
+            this.value = value;
+        }
+
+        public String getKind() {
+            return kind;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof Special)) {
+                return false;
+            }
+            Special that = (Special) o;
+            return this.kind.equals(that.kind) && this.value.equals(that.value);
+        }
+
+        @Override
+        public int hashCode() {
+            return kind.hashCode() * 65 + value.hashCode();
+        }
+
+        public int compareTo(Special that) {
+            int r = this.kind.compareTo(that.kind);
+            if (r != 0) {
+                return r;
+            }
+            return ((Comparable) this.value).compareTo(that.value);
+        }
+
+        @Override
+        public String toString() {
+            int split = kind.indexOf(' ');
+            String pref = kind.substring(0, split < 0 ? 0 : split);
+            String post = kind.substring(split + 1);
+            return pref + value + post;
+        }
+    }
+
+    /** Supports sorting of mixed content.  Sorts strings first,
+     *  then Elements, then everything else (as Comparable).
+     */
+    public static Comparator<Object> contentOrder() {
+        return CONTENT_ORDER;
+    }
+    private static Comparator<Object> CONTENT_ORDER = new ContentComparator();
+
+    private static class ContentComparator implements Comparator<Object> {
+
+        public int compare(Object o1, Object o2) {
+            boolean cs1 = (o1 instanceof CharSequence);
+            boolean cs2 = (o2 instanceof CharSequence);
+            if (cs1 && cs2) {
+                String s1 = (String) fixupString(o1);
+                String s2 = (String) fixupString(o2);
+                return s1.compareTo(s2);
+            }
+            if (cs1) {
+                return 0 - 1;
+            }
+            if (cs2) {
+                return 1 - 0;
+            }
+            boolean el1 = (o1 instanceof Element);
+            boolean el2 = (o2 instanceof Element);
+            if (el1 && el2) {
+                return ((Element) o1).compareTo((Element) o2);
+            }
+            if (el1) {
+                return 0 - 1;
+            }
+            if (el2) {
+                return 1 - 0;
+            }
+            return ((Comparable) o1).compareTo(o2);
+        }
+    }
+
+    /** Used to find, filter, or transform sub-elements.
+     *  When used as a predicate, the filter returns a null
+     *  value for false, and the original object value for true.
+     *  When used as a transformer, the filter may return
+     *  null, for no values, the original object, a new object,
+     *  or an anonymous Element (meaning multiple results).
+     */
+    public interface Filter {
+
+        Object filter(Object value);
+    }
+
+    /** Use this to find an element, perhaps with a given name. */
+    public static class ElementFilter implements Filter {
+
+        /** Subclasses may override this to implement better value tests.
+         *  By default, it returns the element itself, thus recognizing
+         *  all elements, regardless of name.
+         */
+        public Element filter(Element elem) {
+            return elem;  // override this
+        }
+
+        public final Object filter(Object value) {
+            if (!(value instanceof Element)) {
+                return null;
+            }
+            return filter((Element) value);
+        }
+
+        @Override
+        public String toString() {
+            return "<ElementFilter name='*'/>";
+        }
+    }
+    private static Filter elementFilter;
+
+    public static Filter elementFilter() {
+        return (elementFilter != null) ? elementFilter : (elementFilter = new ElementFilter());
+    }
+
+    public static Filter elementFilter(final String name) {
+        name.toString();  // null check
+        return new ElementFilter() {
+
+            @Override
+            public Element filter(Element elem) {
+                return name.equals(elem.name) ? elem : null;
+            }
+
+            @Override
+            public String toString() {
+                return "<ElementFilter name='" + name + "'/>";
+            }
+        };
+    }
+
+    public static Filter elementFilter(final Collection nameSet) {
+        nameSet.getClass();  // null check
+        return new ElementFilter() {
+
+            @Override
+            public Element filter(Element elem) {
+                return nameSet.contains(elem.name) ? elem : null;
+            }
+
+            @Override
+            public String toString() {
+                return "<ElementFilter name='" + nameSet + "'/>";
+            }
+        };
+    }
+
+    public static Filter elementFilter(String... nameSet) {
+        Collection<String> ncoll = Arrays.asList(nameSet);
+        if (nameSet.length > 10) {
+            ncoll = new HashSet<String>(ncoll);
+        }
+        return elementFilter(ncoll);
+    }
+
+    /** Use this to find an element with a named attribute,
+     *  possibly with a particular value.
+     *  (Note that an attribute is missing if and only if its value is null.)
+     */
+    public static class AttrFilter extends ElementFilter {
+
+        protected final String attrName;
+
+        public AttrFilter(String attrName) {
+            this.attrName = attrName.toString();
+        }
+
+        /** Subclasses may override this to implement better value tests.
+         *  By default, it returns true for any non-null value, thus
+         *  recognizing any attribute of the given name, regardless of value.
+         */
+        public boolean test(String attrVal) {
+            return attrVal != null;  // override this
+        }
+
+        @Override
+        public final Element filter(Element elem) {
+            return test(elem.getAttr(attrName)) ? elem : null;
+        }
+
+        @Override
+        public String toString() {
+            return "<AttrFilter name='" + attrName + "' value='*'/>";
+        }
+    }
+
+    public static Filter attrFilter(String attrName) {
+        return new AttrFilter(attrName);
+    }
+
+    public static Filter attrFilter(String attrName, final String attrVal) {
+        if (attrVal == null) {
+            return not(attrFilter(attrName));
+        }
+        return new AttrFilter(attrName) {
+
+            @Override
+            public boolean test(String attrVal2) {
+                return attrVal.equals(attrVal2);
+            }
+
+            @Override
+            public String toString() {
+                return "<AttrFilter name='" + attrName + "' value='" + attrVal + "'/>";
+            }
+        };
+    }
+
+    public static Filter attrFilter(Element matchThis, String attrName) {
+        return attrFilter(attrName, matchThis.getAttr(attrName));
+    }
+
+    /** Use this to find a sub-element of a given class. */
+    public static Filter classFilter(final Class clazz) {
+        return new Filter() {
+
+            public Object filter(Object value) {
+                return clazz.isInstance(value) ? value : null;
+            }
+
+            @Override
+            public String toString() {
+                return "<ClassFilter class='" + clazz.getName() + "'/>";
+            }
+        };
+    }
+    private static Filter textFilter;
+
+    public static Filter textFilter() {
+        return (textFilter != null) ? textFilter : (textFilter = classFilter(CharSequence.class));
+    }
+    private static Filter specialFilter;
+
+    public static Filter specialFilter() {
+        return (specialFilter != null) ? specialFilter : (specialFilter = classFilter(Special.class));
+    }
+    private static Filter selfFilter;
+
+    /** This filter always returns its own argument. */
+    public static Filter selfFilter() {
+        if (selfFilter != null) {
+            return selfFilter;
+        }
+        return selfFilter = new Filter() {
+
+            public Object filter(Object value) {
+                return value;
+            }
+
+            @Override
+            public String toString() {
+                return "<Self/>";
+            }
+        };
+    }
+
+    /** This filter always returns a fixed value, regardless of argument. */
+    public static Filter constantFilter(final Object value) {
+        return new Filter() {
+
+            public Object filter(Object ignore) {
+                return value;
+            }
+
+            @Override
+            public String toString() {
+                return "<Constant>" + value + "</Constant>";
+            }
+        };
+    }
+    private static Filter nullFilter;
+
+    public static Filter nullFilter() {
+        return (nullFilter != null) ? nullFilter : (nullFilter = constantFilter(null));
+    }
+    private static Filter emptyFilter;
+
+    public static Filter emptyFilter() {
+        return (emptyFilter != null) ? emptyFilter : (emptyFilter = constantFilter(Element.EMPTY));
+    }
+
+    /** Use this to invert the logical sense of the given filter. */
+    public static Filter not(final Filter f) {
+        return new Filter() {
+
+            public Object filter(Object value) {
+                return f.filter(value) == null ? value : null;
+            }
+
+            @Override
+            public String toString() {
+                return "<Not>" + f + "</Not>";
+            }
+        };
+    }
+
+    /** Use this to combine several filters with logical AND.
+     *  Returns either the first null or the last non-null value.
+     */
+    public static Filter and(final Filter f0, final Filter f1) {
+        return and(new Filter[]{f0, f1});
+    }
+
+    public static Filter and(final Filter... fs) {
+        switch (fs.length) {
+            case 0:
+                return selfFilter();  // always true (on non-null inputs)
+            case 1:
+                return fs[0];
+        }
+        return new Filter() {
+
+            public Object filter(Object value) {
+                Object res = fs[0].filter(value);
+                if (res != null) {
+                    res = fs[1].filter(value);
+                    for (int i = 2; res != null && i < fs.length; i++) {
+                        res = fs[i].filter(value);
+                    }
+                }
+                return res;
+            }
+
+            @Override
+            public String toString() {
+                return opToString("<And>", fs, "</And>");
+            }
+        };
+    }
+
+    /** Use this to combine several filters with logical OR.
+     *  Returns either the first non-null or the last null value.
+     */
+    public static Filter or(final Filter f0, final Filter f1) {
+        return or(new Filter[]{f0, f1});
+    }
+
+    public static Filter or(final Filter... fs) {
+        switch (fs.length) {
+            case 0:
+                return nullFilter();
+            case 1:
+                return fs[0];
+        }
+        return new Filter() {
+
+            public Object filter(Object value) {
+                Object res = fs[0].filter(value);
+                if (res == null) {
+                    res = fs[1].filter(value);
+                    for (int i = 2; res == null && i < fs.length; i++) {
+                        res = fs[i].filter(value);
+                    }
+                }
+                return res;
+            }
+
+            @Override
+            public String toString() {
+                return opToString("<Or>", fs, "</Or>");
+            }
+        };
+    }
+
+    /** Use this to combine several filters with logical AND,
+     *  and where each non-null result is passed as the argument
+     *  to the next filter.
+     *  Returns either the first null or the last non-null value.
+     */
+    public static Filter stack(final Filter f0, final Filter f1) {
+        return stack(new Filter[]{f0, f1});
+    }
+
+    public static Filter stack(final Filter... fs) {
+        switch (fs.length) {
+            case 0:
+                return nullFilter();
+            case 1:
+                return fs[0];
+        }
+        return new Filter() {
+
+            public Object filter(Object value) {
+                Object res = fs[0].filter(value);
+                if (res != null) {
+                    res = fs[1].filter(res);
+                    for (int i = 2; res != null && i < fs.length; i++) {
+                        res = fs[i].filter(res);
+                    }
+                }
+                return res;
+            }
+
+            @Override
+            public String toString() {
+                return opToString("<Stack>", fs, "</Stack>");
+            }
+        };
+    }
+
+    /** Copy everything produced by f to sink, using addContent. */
+    public static Filter content(final Filter f, final Collection<Object> sink) {
+        return new Filter() {
+
+            public Object filter(Object value) {
+                Object res = f.filter(value);
+                addContent(res, sink);
+                return res;
+            }
+
+            @Override
+            public String toString() {
+                return opToString("<addContent>", new Object[]{f, sink},
+                        "</addContent>");
+            }
+        };
+    }
+
+    /** Look down the tree using f, collecting fx, else recursing into x.
+     *  Identities:
+     *  <code>
+     *     findInTree(f, s) == findInTree(content(f, s))
+     *     findInTree(f)    == replaceInTree(and(f, selfFilter())).
+     *  </code>
+     */
+    public static Filter findInTree(Filter f, Collection<Object> sink) {
+        if (sink != null) {
+            f = content(f, sink);
+        }
+        return findInTree(f);
+    }
+
+    /** Look down the tree using f, recursing into x unless fx. */
+    public static Filter findInTree(final Filter f) {
+        return new Filter() {
+
+            public Object filter(Object value) {
+                Object res = f.filter(value);
+                if (res != null) {
+                    return res;
+                }
+                if (value instanceof Element) {
+                    // recurse
+                    return ((Element) value).find(this);
+                }
+                return null;
+            }
+
+            @Override
+            public String toString() {
+                return opToString("<FindInTree>", new Object[]{f},
+                        "</FindInTree>");
+            }
+        };
+    }
+
+    /** Look down the tree using f.  Replace each x with fx, else recurse.
+     *  If post filter g is given, optionally replace with gx after recursion.
+     */
+    public static Filter replaceInTree(final Filter f, final Filter g) {
+        return new Filter() {
+
+            public Object filter(Object value) {
+                Object res = (f == null) ? null : f.filter(value);
+                if (res != null) {
+                    return res;
+                }
+                if (value instanceof Element) {
+                    // recurse
+                    ((Element) value).replaceAll(this);
+                    // Optional postorder traversal:
+                    if (g != null) {
+                        res = g.filter(value);
+                    }
+                }
+                return res;  // usually null, meaning no replacement
+            }
+
+            @Override
+            public String toString() {
+                return opToString("<ReplaceInTree>",
+                        new Object[]{f, g},
+                        "</ReplaceInTree>");
+            }
+        };
+    }
+
+    public static Filter replaceInTree(Filter f) {
+        f.getClass(); // null check
+        return replaceInTree(f, null);
+    }
+
+    /** Make a filter which calls this method on the given element.
+     *  If the method is static, the first argument is passed the
+     *  the subtree value being filtered.
+     *  If the method is non-static, the receiver is the subtree value itself.
+     *  <p>
+     *  Optionally, additional arguments may be specified.
+     *  <p>
+     *  If the filtered value does not match the receiver class
+     *  (or else the first argument type, if the method is static),
+     *  the filter returns null without invoking the method.
+     *  <p>
+     *  The returned filter value is the result returned from the method.
+     *  Optionally, a non-null special false result value may be specified.
+     *  If the result returned from the method is equal to that false value,
+     *  the filter will return null.
+     */
+    public static Filter methodFilter(java.lang.reflect.Method m, Object[] extraArgs,
+            Object falseResult) {
+        return methodFilter(m, false, extraArgs, falseResult);
+    }
+
+    public static Filter methodFilter(java.lang.reflect.Method m,
+            Object[] args) {
+        return methodFilter(m, args, null);
+    }
+
+    public static Filter methodFilter(java.lang.reflect.Method m) {
+        return methodFilter(m, null, null);
+    }
+
+    public static Filter testMethodFilter(java.lang.reflect.Method m, Object[] extraArgs,
+            Object falseResult) {
+        return methodFilter(m, true, extraArgs, falseResult);
+    }
+
+    public static Filter testMethodFilter(java.lang.reflect.Method m, Object[] extraArgs) {
+        return methodFilter(m, true, extraArgs, zeroArgs.get(m.getReturnType()));
+    }
+
+    public static Filter testMethodFilter(java.lang.reflect.Method m) {
+        return methodFilter(m, true, null, zeroArgs.get(m.getReturnType()));
+    }
+
+    private static Filter methodFilter(final java.lang.reflect.Method m,
+            final boolean isTest,
+            Object[] extraArgs, final Object falseResult) {
+        Class[] params = m.getParameterTypes();
+        final boolean isStatic = java.lang.reflect.Modifier.isStatic(m.getModifiers());
+        int insertLen = (isStatic ? 1 : 0);
+        if (insertLen + (extraArgs == null ? 0 : extraArgs.length) > params.length) {
+            throw new IllegalArgumentException("too many arguments");
+        }
+        final Object[] args = (params.length == insertLen) ? null
+                : new Object[params.length];
+        final Class valueType = !isStatic ? m.getDeclaringClass() : params[0];
+        if (valueType.isPrimitive()) {
+            throw new IllegalArgumentException("filtered value must be reference type");
+        }
+        int fillp = insertLen;
+        if (extraArgs != null) {
+            for (int i = 0; i < extraArgs.length; i++) {
+                args[fillp++] = extraArgs[i];
+            }
+        }
+        if (args != null) {
+            while (fillp < args.length) {
+                Class param = params[fillp];
+                args[fillp++] = param.isPrimitive() ? zeroArgs.get(param) : null;
+            }
+        }
+        final Thread curt = Thread.currentThread();
+        class MFilt implements Filter {
+
+            public Object filter(Object value) {
+                if (!valueType.isInstance(value)) {
+                    return null;  // filter fails quickly
+                }
+                Object[] args1 = args;
+                if (isStatic) {
+                    if (args1 == null) {
+                        args1 = new Object[1];
+                    } else if (curt != Thread.currentThread()) // Dirty hack to curtail array copying in common case.
+                    {
+                        args1 = (Object[]) args1.clone();
+                    }
+                    args1[0] = value;
+                }
+                Object res;
+                try {
+                    res = m.invoke(value, args1);
+                } catch (java.lang.reflect.InvocationTargetException te) {
+                    Throwable ee = te.getCause();
+                    if (ee instanceof RuntimeException) {
+                        throw (RuntimeException) ee;
+                    }
+                    if (ee instanceof Error) {
+                        throw (Error) ee;
+                    }
+                    throw new RuntimeException("throw in filter", ee);
+                } catch (IllegalAccessException ee) {
+                    throw new RuntimeException("access error in filter", ee);
+                }
+                if (res == null) {
+                    if (!isTest && m.getReturnType() == Void.TYPE) {
+                        // Void methods return self by convention.
+                        // (But void "tests" always return false.)
+                        res = value;
+                    }
+                } else {
+                    if (falseResult != null && falseResult.equals(res)) {
+                        res = null;
+                    } else if (isTest) {
+                        // Tests return self by convention.
+                        res = value;
+                    }
+                }
+                return res;
+            }
+
+            @Override
+            public String toString() {
+                return "<Method>" + m + "</Method>";
+            }
+        }
+        return new MFilt();
+    }
+    private static HashMap<Class, Object> zeroArgs = new HashMap<Class, Object>();
+
+    static {
+        zeroArgs.put(Boolean.TYPE, Boolean.FALSE);
+        zeroArgs.put(Character.TYPE, new Character((char) 0));
+        zeroArgs.put(Byte.TYPE, new Byte((byte) 0));
+        zeroArgs.put(Short.TYPE, new Short((short) 0));
+        zeroArgs.put(Integer.TYPE, new Integer(0));
+        zeroArgs.put(Float.TYPE, new Float(0));
+        zeroArgs.put(Long.TYPE, new Long(0));
+        zeroArgs.put(Double.TYPE, new Double(0));
+    }
+
+    private static String opToString(String s1, Object[] s2, String s3) {
+        StringBuilder buf = new StringBuilder(s1);
+        for (int i = 0; i < s2.length; i++) {
+            if (s2[i] != null) {
+                buf.append(s2[i]);
+            }
+        }
+        buf.append(s3);
+        return buf.toString();
+    }
+
+    /** Call the filter on each list element x, and replace x with the
+     *  resulting filter value e, or its parts.
+     *  If e is null, keep x.  (This eases use of partial-domain filters.)
+     *  If e is a TokenList or an anonymous Element, add e's parts
+     *  to the list instead of x.
+     *  Otherwise, replace x by e.
+     *  <p>
+     *  The effect at each list position <code>n</code> may be expressed
+     *  in terms of XMLKit.addContent as follows:
+     *  <pre>
+     *     Object e = f.filter(target.get(n));
+     *     if (e != null) {
+     *         target.remove(n);
+     *         addContent(e, target.subList(n,n));
+     *     }
+     *  </pre>
+     *  <p>
+     *  Note:  To force deletion of x, simply have the filter return
+     *  Element.EMPTY or TokenList.EMPTY.
+     *  To force null filter values to have this effect,
+     *  use the expression: <code>or(f, emptyFilter())</code>.
+     */
+    public static void replaceAll(Filter f, List<Object> target) {
+        for (ListIterator<Object> i = target.listIterator(); i.hasNext();) {
+            Object x = i.next();
+            Object fx = f.filter(x);
+            if (fx == null) {
+                // Unliked addContent, a null is a no-op here.
+                // i.remove();
+            } else if (fx instanceof TokenList) {
+                TokenList tl = (TokenList) fx;
+                if (tl.size() == 1) {
+                    i.set(tl);
+                } else {
+                    i.remove();
+                    for (String part : tl) {
+                        i.add(part);
+                    }
+                }
+            } else if (fx instanceof Element
+                    && ((Element) fx).isAnonymous()) {
+                Element anon = (Element) fx;
+                if (anon.size() == 1) {
+                    i.set(anon);
+                } else {
+                    i.remove();
+                    for (Object part : anon) {
+                        i.add(part);
+                    }
+                }
+            } else if (x != fx) {
+                i.set(fx);
+            }
+        }
+    }
+
+    /** If e is null, return zero.
+     *  If e is a TokenList or an anonymous Element, add e's parts
+     *  to the collection, and return the number of parts.
+     *  Otherwise, add e to the collection, and return one.
+     *  If the collection reference is null, the result is as if
+     *  a throwaway collection were used.
+     */
+    public static int addContent(Object e, Collection<Object> sink) {
+        if (e == null) {
+            return 0;
+        } else if (e instanceof TokenList) {
+            TokenList tl = (TokenList) e;
+            if (sink != null) {
+                sink.addAll(tl);
+            }
+            return tl.size();
+        } else if (e instanceof Element
+                && ((Element) e).isAnonymous()) {
+            Element anon = (Element) e;
+            if (sink != null) {
+                sink.addAll(anon.asList());
+            }
+            return anon.size();
+        } else {
+            if (sink != null) {
+                sink.add(e);
+            }
+            return 1;
+        }
+    }
+
+    static Collection<Object> newCounterColl() {
+        return new AbstractCollection<Object>() {
+
+            int size;
+
+            public int size() {
+                return size;
+            }
+
+            @Override
+            public boolean add(Object o) {
+                ++size;
+                return true;
+            }
+
+            public Iterator<Object> iterator() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    /** SAX2 document handler for building Element trees. */
+    private static class Builder implements ContentHandler, LexicalHandler {
+        /*, EntityResolver, DTDHandler, ErrorHandler*/
+
+        Collection<Object> sink;
+        boolean makeFrozen;
+        boolean tokenizing;
+
+        Builder(Collection<Object> sink, boolean tokenizing, boolean makeFrozen) {
+            this.sink = sink;
+            this.tokenizing = tokenizing;
+            this.makeFrozen = makeFrozen;
+        }
+        Object[] parts = new Object[30];
+        int nparts = 0;
+        int[] attrBases = new int[10];  // index into parts
+        int[] elemBases = new int[10];  // index into parts
+        int depth = -1;  // index into attrBases, elemBases
+        // Parts is organized this way:
+        // | name0 | akey aval ... | subelem ... | name1 | ... |
+        // The position of the first "akey" after name0 is attrBases[0].
+        // The position of the first "subelem" after name0 is elemBases[0].
+        // The position after the last part is always nparts.
+        int mergeableToken = -1;  // index into parts of recent CharSequence
+        boolean inCData = false;
+
+        void addPart(Object x) {
+            //System.out.println("addPart "+x);
+            if (nparts == parts.length) {
+                Object[] newParts = new Object[parts.length * 2];
+                System.arraycopy(parts, 0, newParts, 0, parts.length);
+                parts = newParts;
+            }
+            parts[nparts++] = x;
+        }
+
+        Object getMergeableToken() {
+            if (mergeableToken == nparts - 1) {
+                assert (parts[mergeableToken] instanceof CharSequence);
+                return parts[nparts - 1];
+            } else {
+                return null;
+            }
+        }
+
+        void clearMergeableToken() {
+            if (mergeableToken >= 0) {
+                // Freeze temporary StringBuffers into strings.
+                assert (parts[mergeableToken] instanceof CharSequence);
+                parts[mergeableToken] = parts[mergeableToken].toString();
+                mergeableToken = -1;
+            }
+        }
+
+        void setMergeableToken() {
+            if (mergeableToken != nparts - 1) {
+                clearMergeableToken();
+                mergeableToken = nparts - 1;
+                assert (parts[mergeableToken] instanceof CharSequence);
+            }
+        }
+
+        // ContentHandler callbacks
+        public void startElement(String ns, String localName, String name, Attributes atts) {
+            clearMergeableToken();
+            addPart(name.intern());
+            ++depth;
+            if (depth == attrBases.length) {
+                int oldlen = depth;
+                int newlen = depth * 2;
+                int[] newAB = new int[newlen];
+                int[] newEB = new int[newlen];
+                System.arraycopy(attrBases, 0, newAB, 0, oldlen);
+                System.arraycopy(elemBases, 0, newEB, 0, oldlen);
+                attrBases = newAB;
+                elemBases = newEB;
+            }
+            attrBases[depth] = nparts;
+            // Collect attributes.
+            int na = atts.getLength();
+            for (int k = 0; k < na; k++) {
+                addPart(atts.getQName(k).intern());
+                addPart(atts.getValue(k));
+            }
+            // Get ready to collect elements.
+            elemBases[depth] = nparts;
+        }
+
+        public void endElement(String ns, String localName, String name) {
+            assert (depth >= 0);
+            clearMergeableToken();
+            int ebase = elemBases[depth];
+            int elen = nparts - ebase;
+            int abase = attrBases[depth];
+            int alen = ebase - abase;
+            int nbase = abase - 1;
+            int cap = alen + (makeFrozen ? 0 : NEED_SLOP) + elen;
+            Element e = new Element((String) parts[nbase], elen, cap);
+            // Set up attributes.
+            for (int k = 0; k < alen; k += 2) {
+                e.parts[cap - k - 2] = parts[abase + k + 0];
+                e.parts[cap - k - 1] = parts[abase + k + 1];
+            }
+            // Set up sub-elements.
+            System.arraycopy(parts, ebase, e.parts, 0, elen);
+            // Back out of this level.
+            --depth;
+            nparts = nbase;
+            assert (e.isFrozen() == makeFrozen);
+            assert (e.size() == elen);
+            assert (e.attrSize() * 2 == alen);
+            if (depth >= 0) {
+                addPart(e);
+            } else {
+                sink.add(e);
+            }
+        }
+
+        public void startCDATA() {
+            inCData = true;
+        }
+
+        public void endCDATA() {
+            inCData = false;
+        }
+
+        public void characters(char[] buf, int off, int len) {
+            boolean headSpace = false;
+            boolean tailSpace = false;
+            int firstLen;
+            if (tokenizing && !inCData) {
+                // Strip unquoted blanks.
+                while (len > 0 && isWhitespace(buf[off])) {
+                    headSpace = true;
+                    ++off;
+                    --len;
+                }
+                if (len == 0) {
+                    tailSpace = true;  // it is all space
+                }
+                while (len > 0 && isWhitespace(buf[off + len - 1])) {
+                    tailSpace = true;
+                    --len;
+                }
+                firstLen = 0;
+                while (firstLen < len && !isWhitespace(buf[off + firstLen])) {
+                    ++firstLen;
+                }
+            } else {
+                firstLen = len;
+            }
+            if (headSpace) {
+                clearMergeableToken();
+            }
+            boolean mergeAtEnd = !tailSpace;
+            // If buffer was empty, or had only ignorable blanks, do nothing.
+            if (len == 0) {
+                return;
+            }
+            // Decide whether to merge some of these chars into a previous token.
+            Object prev = getMergeableToken();
+            if (prev instanceof StringBuffer) {
+                ((StringBuffer) prev).append(buf, off, firstLen);
+            } else if (prev == null) {
+                addPart(new String(buf, off, firstLen));
+            } else {
+                // Merge two strings.
+                String prevStr = prev.toString();
+                StringBuffer prevBuf = new StringBuffer(prevStr.length() + firstLen);
+                prevBuf.append(prevStr);
+                prevBuf.append(buf, off, firstLen);
+                if (mergeAtEnd && len == firstLen) {
+                    // Replace previous string with new StringBuffer.
+                    parts[nparts - 1] = prevBuf;
+                } else {
+                    // Freeze it now.
+                    parts[nparts - 1] = prevBuf.toString();
+                }
+            }
+            off += firstLen;
+            len -= firstLen;
+            if (len > 0) {
+                // Appended only the first token.
+                clearMergeableToken();
+                // Add the rest as separate parts.
+                while (len > 0) {
+                    while (len > 0 && isWhitespace(buf[off])) {
+                        ++off;
+                        --len;
+                    }
+                    int nextLen = 0;
+                    while (nextLen < len && !isWhitespace(buf[off + nextLen])) {
+                        ++nextLen;
+                    }
+                    assert (nextLen > 0);
+                    addPart(new String(buf, off, nextLen));
+                    off += nextLen;
+                    len -= nextLen;
+                }
+            }
+            if (mergeAtEnd) {
+                setMergeableToken();
+            }
+        }
+
+        public void ignorableWhitespace(char[] buf, int off, int len) {
+            clearMergeableToken();
+            if (false) {
+                characters(buf, off, len);
+                clearMergeableToken();
+            }
+        }
+
+        public void comment(char[] buf, int off, int len) {
+            addPart(new Special("<!-- -->", new String(buf, off, len)));
+        }
+
+        public void processingInstruction(String name, String instruction) {
+            Element pi = new Element(name);
+            pi.add(instruction);
+            addPart(new Special("<? ?>", pi));
+        }
+
+        public void skippedEntity(String name) {
+        }
+
+        public void startDTD(String name, String publicId, String systemId) {
+        }
+
+        public void endDTD() {
+        }
+
+        public void startEntity(String name) {
+        }
+
+        public void endEntity(String name) {
+        }
+
+        public void setDocumentLocator(org.xml.sax.Locator locator) {
+        }
+
+        public void startDocument() {
+        }
+
+        public void endDocument() {
+        }
+
+        public void startPrefixMapping(String prefix, String uri) {
+        }
+
+        public void endPrefixMapping(String prefix) {
+        }
+    }
+
+    /** Produce a ContentHandler for use with an XML parser.
+     *  The object is <em>also</em> a LexicalHandler.
+     *  Every top-level Element produced will get added to sink.
+     *  All elements will be frozen iff makeFrozen is true.
+     */
+    public static ContentHandler makeBuilder(Collection<Object> sink, boolean tokenizing, boolean makeFrozen) {
+        return new Builder(sink, tokenizing, makeFrozen);
+    }
+
+    public static ContentHandler makeBuilder(Collection<Object> sink, boolean tokenizing) {
+        return new Builder(sink, tokenizing, false);
+    }
+
+    public static ContentHandler makeBuilder(Collection<Object> sink) {
+        return makeBuilder(sink, false, false);
+    }
+
+    public static Element readFrom(Reader in, boolean tokenizing, boolean makeFrozen) throws IOException {
+        Element sink = new Element();
+        ContentHandler b = makeBuilder(sink.asList(), tokenizing, makeFrozen);
+        XMLReader parser;
+        try {
+            parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
+        } catch (SAXException ee) {
+            throw new Error(ee);
+        }
+        //parser.setFastStandalone(true);
+        parser.setContentHandler(b);
+        try {
+            parser.setProperty("http://xml.org/sax/properties/lexical-handler",
+                    (LexicalHandler) b);
+        } catch (SAXException ee) {
+            // Ignore.  We will miss the comments and whitespace.
+        }
+        try {
+            parser.parse(new InputSource(in));
+        } catch (SAXParseException ee) {
+            throw new RuntimeException("line " + ee.getLineNumber() + " col " + ee.getColumnNumber() + ": ", ee);
+        } catch (SAXException ee) {
+            throw new RuntimeException(ee);
+        }
+        switch (sink.size()) {
+            case 0:
+                return null;
+            case 1:
+                if (sink.get(0) instanceof Element) {
+                    return (Element) sink.get(0);
+                }
+            // fall through
+            default:
+                if (makeFrozen) {
+                    sink.shallowFreeze();
+                }
+                return sink;
+        }
+    }
+
+    public static Element readFrom(Reader in, boolean tokenizing) throws IOException {
+        return readFrom(in, tokenizing, false);
+    }
+
+    public static Element readFrom(Reader in) throws IOException {
+        return readFrom(in, false, false);
+    }
+
+    public static void prettyPrintTo(OutputStream out, Element e) throws IOException {
+        prettyPrintTo(new OutputStreamWriter(out), e);
+    }
+
+    public static void prettyPrintTo(Writer out, Element e) throws IOException {
+        Printer pr = new Printer(out);
+        pr.pretty = true;
+        pr.print(e);
+    }
+
+    static class Outputter {
+
+        ContentHandler ch;
+        LexicalHandler lh;
+
+        Outputter(ContentHandler ch, LexicalHandler lh) {
+            this.ch = ch;
+            this.lh = lh;
+        }
+        AttributesImpl atts = new AttributesImpl();  // handy
+
+        void output(Object x) throws SAXException {
+            // Cf. jdom.org/jdom-b8/src/java/org/jdom/output/SAXOutputter.java
+            if (x instanceof Element) {
+                Element e = (Element) x;
+                atts.clear();
+                for (int asize = e.attrSize(), k = 0; k < asize; k++) {
+                    String key = e.getAttrName(k);
+                    String val = e.getAttr(k);
+                    atts.addAttribute("", "", key, "CDATA", val);
+                }
+                ch.startElement("", "", e.getName(), atts);
+                for (int i = 0; i < e.size(); i++) {
+                    output(e.get(i));
+                }
+                ch.endElement("", "", e.getName());
+            } else if (x instanceof Special) {
+                Special sp = (Special) x;
+                if (sp.kind.startsWith("<!--")) {
+                    char[] chars = sp.value.toString().toCharArray();
+                    lh.comment(chars, 0, chars.length);
+                } else if (sp.kind.startsWith("<?")) {
+                    Element nameInstr = (Element) sp.value;
+                    ch.processingInstruction(nameInstr.name,
+                            nameInstr.get(0).toString());
+                } else {
+                    // drop silently
+                }
+            } else {
+                char[] chars = x.toString().toCharArray();
+                ch.characters(chars, 0, chars.length);
+            }
+        }
+    }
+
+    public static class Printer {
+
+        public Writer w;
+        public boolean tokenizing;
+        public boolean pretty;
+        public boolean abbreviated;  // nonstandard format cuts down on noise
+        int depth = 0;
+        boolean prevStr;
+        int tabStop = 2;
+
+        public Printer(Writer w) {
+            this.w = w;
+        }
+
+        public Printer() {
+            StringWriter sw = new StringWriter();
+            this.w = sw;
+
+        }
+
+        public String nextString() {
+            StringBuffer sb = ((StringWriter) w).getBuffer();
+            String next = sb.toString();
+            sb.setLength(0);  // reset
+            return next;
+        }
+
+        void indent(int depth) throws IOException {
+            if (depth > 0) {
+                w.write("\n");
+            }
+            int nsp = tabStop * depth;
+            while (nsp > 0) {
+                String s = "                ";
+                String t = s.substring(0, nsp < s.length() ? nsp : s.length());
+                w.write(t);
+                nsp -= t.length();
+            }
+        }
+
+        public void print(Element e) throws IOException {
+            if (e.isAnonymous()) {
+                printParts(e);
+                return;
+            }
+            printRecursive(e);
+        }
+
+        public void println(Element e) throws IOException {
+            print(e);
+            w.write("\n");
+            w.flush();
+        }
+
+        public void printRecursive(Element e) throws IOException {
+            boolean indented = false;
+            if (pretty && !prevStr && e.size() + e.attrSize() > 0) {
+                indent(depth);
+                indented = true;
+            }
+            w.write("<");
+            w.write(e.name);
+            for (int asize = e.attrSize(), k = 0; k < asize; k++) {
+                String key = e.getAttrName(k);
+                String val = e.getAttr(k);
+                w.write(" ");
+                w.write(key);
+                w.write("=");
+                if (val == null) {
+                    w.write("null");  // Should not happen....
+                } else if (val.indexOf("\"") < 0) {
+                    w.write("\"");
+                    writeToken(val, '"', w);
+                    w.write("\"");
+                } else {
+                    w.write("'");
+                    writeToken(val, '\'', w);
+                    w.write("'");
+                }
+            }
+            if (e.size() == 0) {
+                w.write("/>");
+            } else {
+                ++depth;
+                if (abbreviated) {
+                    w.write("/");
+                } else {
+                    w.write(">");
+                }
+                prevStr = false;
+                printParts(e);
+                if (abbreviated) {
+                    w.write(">");
+                } else {
+                    if (indented && !prevStr) {
+                        indent(depth - 1);
+                    }
+                    w.write("</");
+                    w.write(e.name);
+                    w.write(">");
+                }
+                prevStr = false;
+                --depth;
+            }
+        }
+
+        private void printParts(Element e) throws IOException {
+            for (int i = 0; i < e.size(); i++) {
+                Object x = e.get(i);
+                if (x instanceof Element) {
+                    printRecursive((Element) x);
+                    prevStr = false;
+                } else if (x instanceof Special) {
+                    w.write(((Special) x).toString());
+                    prevStr = false;
+                } else {
+                    String s = String.valueOf(x);
+                    if (pretty) {
+                        s = s.trim();
+                        if (s.length() == 0) {
+                            continue;
+                        }
+                    }
+                    if (prevStr) {
+                        w.write(' ');
+                    }
+                    writeToken(s, tokenizing ? ' ' : (char) -1, w);
+                    prevStr = true;
+                }
+                if (pretty && depth == 0) {
+                    w.write("\n");
+                    prevStr = false;
+                }
+            }
+        }
+    }
+
+    public static void output(Object e, ContentHandler ch, LexicalHandler lh) throws SAXException {
+        new Outputter(ch, lh).output(e);
+    }
+
+    public static void output(Object e, ContentHandler ch) throws SAXException {
+        if (ch instanceof LexicalHandler) {
+            output(e, ch, (LexicalHandler) ch);
+        } else {
+            output(e, ch, null);
+        }
+    }
+
+    public static void writeToken(String val, char quote, Writer w) throws IOException {
+        int len = val.length();
+        boolean canUseCData = (quote != '"' && quote != '\'');
+        int vpos = 0;
+        for (int i = 0; i < len; i++) {
+            char ch = val.charAt(i);
+            if ((ch == '<' || ch == '&' || ch == '>' || ch == quote)
+                    || (quote == ' ' && isWhitespace(ch))) {
+                if (canUseCData) {
+                    assert (vpos == 0);
+                    writeCData(val, w);
+                    return;
+                } else {
+                    if (vpos < i) {
+                        w.write(val, vpos, i - vpos);
+                    }
+                    String esc;
+                    switch (ch) {
+                        case '&':
+                            esc = "&amp;";
+                            break;
+                        case '<':
+                            esc = "&lt;";
+                            break;
+                        case '\'':
+                            esc = "&apos;";
+                            break;
+                        case '"':
+                            esc = "&quot;";
+                            break;
+                        case '>':
+                            esc = "&gt;";
+                            break;
+                        default:
+                            esc = "&#" + (int) ch + ";";
+                            break;
+                    }
+                    w.write(esc);
+                    vpos = i + 1;  // skip escaped char
+                }
+            }
+        }
+        // write the unquoted tail
+        w.write(val, vpos, val.length() - vpos);
+    }
+
+    public static void writeCData(String val, Writer w) throws IOException {
+        String begCData = "<![CDATA[";
+        String endCData = "]]>";
+        w.write(begCData);
+        for (int vpos = 0, split;; vpos = split) {
+            split = val.indexOf(endCData, vpos);
+            if (split < 0) {
+                w.write(val, vpos, val.length() - vpos);
+                w.write(endCData);
+                return;
+            }
+            split += 2; // bisect the "]]>" goo
+            w.write(val, vpos, split - vpos);
+            w.write(endCData);
+            w.write(begCData);
+        }
+    }
+
+    public static TokenList convertToList(String str) {
+        if (str == null) {
+            return null;
+        }
+        return new TokenList(str);
+    }
+
+    /** If str is null, empty, or blank, returns null.
+     *  Otherwise, return a Double if str spells a double value and contains '.' or 'e'.
+     *  Otherwise, return an Integer if str spells an int value.
+     *  Otherwise, return a Long if str spells a long value.
+     *  Otherwise, return a BigInteger for the string.
+     *  Otherwise, throw NumberFormatException.
+     */
+    public static Number convertToNumber(String str) {
+        if (str == null) {
+            return null;
+        }
+        str = str.trim();
+        if (str.length() == 0) {
+            return null;
+        }
+        if (str.indexOf('.') >= 0
+                || str.indexOf('e') >= 0
+                || str.indexOf('E') >= 0) {
+            return Double.valueOf(str);
+        }
+        try {
+            long lval = Long.parseLong(str);
+            if (lval == (int) lval) {
+                // Narrow to Integer, if possible.
+                return new Integer((int) lval);
+            }
+            return new Long(lval);
+        } catch (NumberFormatException ee) {
+            // Could not represent it as a long.
+            return new java.math.BigInteger(str, 10);
+        }
+    }
+
+    public static Number convertToNumber(String str, Number dflt) {
+        Number n = convertToNumber(str);
+        return (n == null) ? dflt : n;
+    }
+
+    public static long convertToLong(String str) {
+        return convertToLong(str, 0);
+    }
+
+    public static long convertToLong(String str, long dflt) {
+        Number n = convertToNumber(str);
+        return (n == null) ? dflt : n.longValue();
+    }
+
+    public static double convertToDouble(String str) {
+        return convertToDouble(str, 0);
+    }
+
+    public static double convertToDouble(String str, double dflt) {
+        Number n = convertToNumber(str);
+        return (n == null) ? dflt : n.doubleValue();
+    }
+
+    // Testing:
+    public static void main(String... av) throws Exception {
+        Element.method("getAttr");
+        //new org.jdom.input.SAXBuilder().build(file).getRootElement();
+        //jdom.org/jdom-b8/src/java/org/jdom/input/SAXBuilder.java
+        //Document build(InputSource in) throws JDOMException
+
+        int reps = 0;
+
+        boolean tokenizing = false;
+        boolean makeFrozen = false;
+        if (av.length > 0) {
+            tokenizing = true;
+            try {
+                reps = Integer.parseInt(av[0]);
+            } catch (NumberFormatException ee) {
+            }
+        }
+        Reader inR = new BufferedReader(new InputStreamReader(System.in));
+        String inS = null;
+        if (reps > 1) {
+            StringWriter inBufR = new StringWriter(1 << 14);
+            char[] cbuf = new char[1024];
+            for (int nr; (nr = inR.read(cbuf)) >= 0;) {
+                inBufR.write(cbuf, 0, nr);
+            }
+            inS = inBufR.toString();
+            inR = new StringReader(inS);
+        }
+        Element e = XMLKit.readFrom(inR, tokenizing, makeFrozen);
+        System.out.println("transform = " + e.findAll(methodFilter(Element.method("prettyString"))));
+        System.out.println("transform = " + e.findAll(testMethodFilter(Element.method("hasText"))));
+        long tm0 = 0;
+        int warmup = 10;
+        for (int i = 1; i < reps; i++) {
+            inR = new StringReader(inS);
+            readFrom(inR, tokenizing, makeFrozen);
+            if (i == warmup) {
+                System.out.println("Start timing...");
+                tm0 = System.currentTimeMillis();
+            }
+        }
+        if (tm0 != 0) {
+            long tm1 = System.currentTimeMillis();
+            System.out.println((reps - warmup) + " in " + (tm1 - tm0) + " ms");
+        }
+        System.out.println("hashCode = " + e.hashCode());
+        String eStr = e.toString();
+        System.out.println(eStr);
+        Element e2 = readFrom(new StringReader(eStr), tokenizing, !makeFrozen);
+        System.out.println("hashCode = " + e2.hashCode());
+        if (!e.equals(e2)) {
+            System.out.println("**** NOT EQUAL 1\n" + e2);
+        }
+        e = e.deepCopy();
+        System.out.println("hashCode = " + e.hashCode());
+        if (!e.equals(e2)) {
+            System.out.println("**** NOT EQUAL 2");
+        }
+        e2.shallowFreeze();
+        System.out.println("hashCode = " + e2.hashCode());
+        if (!e.equals(e2)) {
+            System.out.println("**** NOT EQUAL 3");
+        }
+        if (false) {
+            System.out.println(e);
+        } else {
+            prettyPrintTo(new OutputStreamWriter(System.out), e);
+        }
+        System.out.println("Flat text:|" + e.getFlatText() + "|");
+        {
+            System.out.println("<!--- Sorted: --->");
+            Element ce = e.copyContentOnly();
+            ce.sort();
+            prettyPrintTo(new OutputStreamWriter(System.out), ce);
+        }
+        {
+            System.out.println("<!--- Trimmed: --->");
+            Element tr = e.deepCopy();
+            findInTree(testMethodFilter(Element.method("trimText"))).filter(tr);
+            System.out.println(tr);
+        }
+        {
+            System.out.println("<!--- Unstrung: --->");
+            Element us = e.deepCopy();
+            int nr = us.retainAllInTree(elementFilter(), null);
+            System.out.println("nr=" + nr);
+            System.out.println(us);
+        }
+        {
+            System.out.println("<!--- Rollup: --->");
+            Element ru = e.deepCopy();
+            Filter makeAnonF =
+                    methodFilter(Element.method("setName"),
+                    new Object[]{ANON_NAME});
+            Filter testSizeF =
+                    testMethodFilter(Element.method("size"));
+            Filter walk =
+                    replaceInTree(and(not(elementFilter()), emptyFilter()),
+                    and(testSizeF, makeAnonF));
+            ru = (Element) walk.filter(ru);
+            //System.out.println(ru);
+            prettyPrintTo(new OutputStreamWriter(System.out), ru);
+        }
+    }
+
+    static boolean isWhitespace(char c) {
+        switch (c) {
+            case 0x20:
+            case 0x09:
+            case 0x0D:
+            case 0x0A:
+                return true;
+        }
+        return false;
+    }
+}
--- a/langtools/.hgtags	Tue Aug 31 15:05:09 2010 +0400
+++ b/langtools/.hgtags	Thu Sep 02 12:17:21 2010 -0700
@@ -79,3 +79,6 @@
 ff9c0a0bf7edf637a7dac5062b920924536ed79c jdk7-b102
 bd85271c580ce4600b1b2d5598daa19d02174cf7 jdk7-b103
 fc7219517ec16b28d729d259020a25b05ffdf0b6 jdk7-b104
+aaecac256d39c7cb536e70d20ddd833fc118e43a jdk7-b105
+112fcc00659dda1a356ec75d964584e4dae0228f jdk7-b106
+2c1c657f69a4ff608a43e1ac61baf3294cd55797 jdk7-b107