changeset 1430:0fcfcfd6162e

Merge from main OpenJDK repository
author Greg Lewis <glewis@eyesbeyond.com>
date Mon, 19 Apr 2010 20:41:10 -0700
parents 1e976d3fd820 765578777b6e
children 88f9b6ef43ff
files src/cpu/x86/vm/stubGenerator_x86_64.cpp src/cpu/x86/vm/templateTable_x86_32.cpp src/share/vm/gc_implementation/includeDB_gc_parallelScavenge src/share/vm/includeDB_core src/share/vm/runtime/globals.hpp
diffstat 151 files changed, 4373 insertions(+), 1086 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sat Mar 20 11:12:00 2010 -0700
+++ b/.hgtags	Mon Apr 19 20:41:10 2010 -0700
@@ -84,3 +84,7 @@
 6c9796468b91dcbb39e09dfa1baf9779ac45eb66 jdk7-b85
 418bc80ce13995149eadc9eecbba21d7a9fa02ae hs17-b10
 bf823ef06b4f211e66988d76a2e2669be5c0820e jdk7-b86
+07226e9eab8f74b37346b32715f829a2ef2c3188 hs18-b01
+e7e7e36ccdb5d56edd47e5744351202d38f3b7ad jdk7-b87
+4b60f23c42231f7ecd62ad1fcb6a9ca26fa57d1b jdk7-b88
+15836273ac2494f36ef62088bc1cb6f3f011f565 jdk7-b89
--- a/agent/src/os/linux/libproc_impl.c	Sat Mar 20 11:12:00 2010 -0700
+++ b/agent/src/os/linux/libproc_impl.c	Mon Apr 19 20:41:10 2010 -0700
@@ -174,7 +174,7 @@
       return NULL;
    }
 
-   newlib->symtab = build_symtab(newlib->fd);
+   newlib->symtab = build_symtab(newlib->fd, libname);
    if (newlib->symtab == NULL) {
       print_debug("symbol table build failed for %s\n", newlib->name);
    }
--- a/agent/src/os/linux/symtab.c	Sat Mar 20 11:12:00 2010 -0700
+++ b/agent/src/os/linux/symtab.c	Mon Apr 19 20:41:10 2010 -0700
@@ -53,8 +53,274 @@
   struct hsearch_data *hash_table;
 } symtab_t;
 
-// read symbol table from given fd.
-struct symtab* build_symtab(int fd) {
+
+// Directory that contains global debuginfo files.  In theory it
+// should be possible to change this, but in a Java environment there
+// is no obvious place to put a user interface to do it.  Maybe this
+// could be set with an environment variable.
+static const char debug_file_directory[] = "/usr/lib/debug";
+
+/* The CRC used in gnu_debuglink, retrieved from
+   http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files. */
+unsigned int gnu_debuglink_crc32 (unsigned int crc,
+                                  unsigned char *buf, size_t len)
+{
+  static const unsigned int crc32_table[256] =
+    {
+      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+      0x2d02ef8d
+    };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;
+}
+
+/* Open a debuginfo file and check its CRC.  If it exists and the CRC
+   matches return its fd.  */
+static int
+open_debug_file (const char *pathname, unsigned int crc)
+{
+  unsigned int file_crc = 0;
+  unsigned char buffer[8 * 1024];
+
+  int fd = pathmap_open(pathname);
+
+  if (fd < 0)
+    return -1;
+
+  lseek(fd, 0, SEEK_SET);
+
+  for (;;) {
+    int len = read(fd, buffer, sizeof buffer);
+    if (len <= 0)
+      break;
+    file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
+  }
+
+  if (crc == file_crc)
+    return fd;
+  else {
+    close(fd);
+    return -1;
+  }
+}
+
+/* Find an ELF section.  */
+static struct elf_section *find_section_by_name(char *name,
+                                                int fd,
+                                                ELF_EHDR *ehdr,
+                                                ELF_SHDR *shbuf,
+                                                struct elf_section *scn_cache)
+{
+  ELF_SHDR* cursct = NULL;
+  char *strtab;
+  int cnt;
+
+  if (scn_cache[ehdr->e_shstrndx].c_data == NULL) {
+    if ((scn_cache[ehdr->e_shstrndx].c_data
+         = read_section_data(fd, ehdr, cursct)) == NULL) {
+      return NULL;
+    }
+  }
+
+  strtab = scn_cache[ehdr->e_shstrndx].c_data;
+
+  for (cursct = shbuf, cnt = 0;
+       cnt < ehdr->e_shnum;
+       cnt++, cursct++) {
+    if (strcmp(cursct->sh_name + strtab, name) == 0) {
+      scn_cache[cnt].c_data = read_section_data(fd, ehdr, cursct);
+      return &scn_cache[cnt];
+    }
+  }
+
+  return NULL;
+}
+
+/* Look for a ".gnu_debuglink" section.  If one exists, try to open a
+   suitable debuginfo file.  */
+static int open_file_from_debug_link(const char *name,
+                                     int fd,
+                                     ELF_EHDR *ehdr,
+                                     ELF_SHDR *shbuf,
+                                     struct elf_section *scn_cache)
+{
+  int debug_fd;
+  struct elf_section *debug_link = find_section_by_name(".gnu_debuglink", fd, ehdr,
+                                                        shbuf, scn_cache);
+  if (debug_link == NULL)
+    return -1;
+  char *debug_filename = debug_link->c_data;
+  int offset = (strlen(debug_filename) + 4) >> 2;
+  static unsigned int crc;
+  crc = ((unsigned int*)debug_link->c_data)[offset];
+  char *debug_pathname = malloc(strlen(debug_filename)
+                                + strlen(name)
+                                + strlen(".debug/")
+                                + strlen(debug_file_directory)
+                                + 2);
+  strcpy(debug_pathname, name);
+  char *last_slash = strrchr(debug_pathname, '/');
+  if (last_slash == NULL)
+    return -1;
+
+  /* Look in the same directory as the object.  */
+  strcpy(last_slash+1, debug_filename);
+
+  debug_fd = open_debug_file(debug_pathname, crc);
+  if (debug_fd >= 0) {
+    free(debug_pathname);
+    return debug_fd;
+  }
+
+  /* Look in a subdirectory named ".debug".  */
+  strcpy(last_slash+1, ".debug/");
+  strcat(last_slash, debug_filename);
+
+  debug_fd = open_debug_file(debug_pathname, crc);
+  if (debug_fd >= 0) {
+    free(debug_pathname);
+    return debug_fd;
+  }
+
+  /* Look in /usr/lib/debug + the full pathname.  */
+  strcpy(debug_pathname, debug_file_directory);
+  strcat(debug_pathname, name);
+  last_slash = strrchr(debug_pathname, '/');
+  strcpy(last_slash+1, debug_filename);
+
+  debug_fd = open_debug_file(debug_pathname, crc);
+  if (debug_fd >= 0) {
+    free(debug_pathname);
+    return debug_fd;
+  }
+
+  free(debug_pathname);
+  return -1;
+}
+
+static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo);
+
+/* Look for a ".gnu_debuglink" section.  If one exists, try to open a
+   suitable debuginfo file and read a symbol table from it.  */
+static struct symtab *build_symtab_from_debug_link(const char *name,
+                                     int fd,
+                                     ELF_EHDR *ehdr,
+                                     ELF_SHDR *shbuf,
+                                     struct elf_section *scn_cache)
+{
+  fd = open_file_from_debug_link(name, fd, ehdr, shbuf, scn_cache);
+
+  if (fd >= 0) {
+    struct symtab *symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false);
+    close(fd);
+    return symtab;
+  }
+
+  return NULL;
+}
+
+// Given a build_id, find the associated debuginfo file
+static char *
+build_id_to_debug_filename (size_t size, unsigned char *data)
+{
+  char *filename, *s;
+
+  filename = malloc(strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
+                    + 2 * size + (sizeof ".debug" - 1) + 1);
+  s = filename + sprintf (filename, "%s/.build-id/", debug_file_directory);
+  if (size > 0)
+    {
+      size--;
+      s += sprintf (s, "%02x", *data++);
+    }
+  if (size > 0)
+    *s++ = '/';
+  while (size-- > 0)
+    s += sprintf (s, "%02x", *data++);
+  strcpy (s, ".debug");
+
+  return filename;
+}
+
+// Read a build ID note.  Try to open any associated debuginfo file
+// and return its symtab
+static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note)
+{
+  int fd;
+  struct symtab *symtab = NULL;
+
+  unsigned char *bytes
+    = (unsigned char*)(note+1) + note->n_namesz;
+  unsigned char *filename
+    = (build_id_to_debug_filename (note->n_descsz, bytes));
+
+  fd = pathmap_open(filename);
+  if (fd >= 0) {
+    symtab = build_symtab_internal(fd, NULL, /* try_debuginfo */ false);
+    close(fd);
+  }
+  free(filename);
+
+  return symtab;
+}
+
+// read symbol table from given fd.  If try_debuginfo) is true, also
+// try to open an associated debuginfo file
+static struct symtab* build_symtab_internal(int fd, const char *filename, bool try_debuginfo) {
   ELF_EHDR ehdr;
   char *names = NULL;
   struct symtab* symtab = NULL;
@@ -66,6 +332,7 @@
   ELF_SHDR* cursct = NULL;
   ELF_PHDR* phbuf = NULL;
   ELF_PHDR* phdr = NULL;
+  int sym_section = SHT_DYNSYM;
 
   uintptr_t baseaddr = (uintptr_t)-1;
 
@@ -90,18 +357,23 @@
 
   for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
     scn_cache[cnt].c_shdr = cursct;
-    if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB) {
+    if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB
+        || cursct->sh_type == SHT_NOTE || cursct->sh_type == SHT_DYNSYM) {
       if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
          goto quit;
       }
     }
+    if (cursct->sh_type == SHT_SYMTAB) {
+      // Full symbol table available so use that
+      sym_section = cursct->sh_type;
+    }
     cursct++;
   }
 
   for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
     ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
 
-    if (shdr->sh_type == SHT_SYMTAB) {
+    if (shdr->sh_type == sym_section) {
       ELF_SYM  *syms;
       int j, n, rslt;
       size_t size;
@@ -163,6 +435,45 @@
     }
   }
 
+  // Look for a separate debuginfo file.
+  if (try_debuginfo) {
+
+    // We prefer a debug symtab to an object's own symtab, so look in
+    // the debuginfo file.  We stash a copy of the old symtab in case
+    // there is no debuginfo.
+    struct symtab* prev_symtab = symtab;
+    symtab = NULL;
+
+#ifdef NT_GNU_BUILD_ID
+    // First we look for a Build ID
+    for (cursct = shbuf, cnt = 0;
+         symtab == NULL && cnt < ehdr.e_shnum;
+         cnt++) {
+      if (cursct->sh_type == SHT_NOTE) {
+        Elf64_Nhdr *note = (Elf64_Nhdr *)scn_cache[cnt].c_data;
+        if (note->n_type == NT_GNU_BUILD_ID) {
+          symtab = build_symtab_from_build_id(note);
+        }
+      }
+      cursct++;
+    }
+#endif
+
+    // Then, if that doesn't work, the debug link
+    if (symtab == NULL) {
+      symtab = build_symtab_from_debug_link(filename, fd, &ehdr, shbuf,
+                                            scn_cache);
+    }
+
+    // If we still haven't found a symtab, use the object's own symtab.
+    if (symtab != NULL) {
+      if (prev_symtab != NULL)
+        destroy_symtab(prev_symtab);
+    } else {
+      symtab = prev_symtab;
+    }
+  }
+
 quit:
   if (shbuf) free(shbuf);
   if (phbuf) free(phbuf);
@@ -177,6 +488,11 @@
   return symtab;
 }
 
+struct symtab* build_symtab(int fd, const char *filename) {
+  return build_symtab_internal(fd, filename, /* try_debuginfo */ true);
+}
+
+
 void destroy_symtab(struct symtab* symtab) {
   if (!symtab) return;
   if (symtab->strs) free(symtab->strs);
--- a/agent/src/os/linux/symtab.h	Sat Mar 20 11:12:00 2010 -0700
+++ b/agent/src/os/linux/symtab.h	Mon Apr 19 20:41:10 2010 -0700
@@ -32,7 +32,7 @@
 struct symtab;
 
 // build symbol table for a given ELF file descriptor
-struct symtab* build_symtab(int fd);
+struct symtab* build_symtab(int fd, const char *filename);
 
 // destroy the symbol table
 void destroy_symtab(struct symtab* symtab);
--- a/make/hotspot_version	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/hotspot_version	Mon Apr 19 20:41:10 2010 -0700
@@ -31,11 +31,11 @@
 #
 
 # Don't put quotes (fail windows build).
-HOTSPOT_VM_COPYRIGHT=Copyright 2009
+HOTSPOT_VM_COPYRIGHT=Copyright 2010
 
-HS_MAJOR_VER=17
+HS_MAJOR_VER=18
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=10
+HS_BUILD_NUMBER=02
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/linux/makefiles/build_vm_def.sh	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+nm --defined-only $* | awk '
+   { if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";" }
+   '
--- a/make/linux/makefiles/mapfile-vers-debug	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/linux/makefiles/mapfile-vers-debug	Mon Apr 19 20:41:10 2010 -0700
@@ -290,6 +290,9 @@
 
                 # This is for Forte Analyzer profiling support.
                 AsyncGetCallTrace;
+
+		# INSERT VTABLE SYMBOLS HERE
+
         local:
                 *;
 };
--- a/make/linux/makefiles/mapfile-vers-product	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/linux/makefiles/mapfile-vers-product	Mon Apr 19 20:41:10 2010 -0700
@@ -285,6 +285,9 @@
 
                 # This is for Forte Analyzer profiling support.
                 AsyncGetCallTrace;
+
+		# INSERT VTABLE SYMBOLS HERE
+
         local:
                 *;
 };
--- a/make/linux/makefiles/vm.make	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/linux/makefiles/vm.make	Mon Apr 19 20:41:10 2010 -0700
@@ -121,14 +121,21 @@
 
 vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES))
 
-mapfile : $(MAPFILE)
+mapfile : $(MAPFILE) vm.def
 	rm -f $@
-	cat $^ > $@
+	awk '{ if ($$0 ~ "INSERT VTABLE SYMBOLS HERE")	\
+                 { system ("cat vm.def"); }		\
+               else					\
+                 { print $$0 }				\
+             }' > $@ < $(MAPFILE)
 
 mapfile_reorder : mapfile $(REORDERFILE)
 	rm -f $@
 	cat $^ > $@
 
+vm.def: $(Res_Files) $(Obj_Files)
+	sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
+
 ifeq ($(ZERO_LIBARCH), ppc64)
   STATIC_CXX = false
 else
--- a/make/windows/build.bat	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/windows/build.bat	Mon Apr 19 20:41:10 2010 -0700
@@ -28,6 +28,9 @@
 REM Since we don't have uname and we could be cross-compiling,
 REM Use the compiler to determine which ARCH we are building
 REM 
+REM Note: Running this batch file from the Windows command shell requires
+REM that "grep" be accessible on the PATH. An MKS install does this.
+REM 
 cl 2>&1 | grep "IA-64" >NUL
 if %errorlevel% == 0 goto isia64
 cl 2>&1 | grep "AMD64" >NUL
@@ -57,11 +60,12 @@
 if "%1" == "product"   goto test1
 if "%1" == "debug"     goto test1
 if "%1" == "fastdebug" goto test1
+if "%1" == "tree"      goto test1
 goto usage
 
 :test1
 if "%2" == "core"      goto test2
-if "%2" == "kernel"   goto test2
+if "%2" == "kernel"    goto test2
 if "%2" == "compiler1" goto test2
 if "%2" == "compiler2" goto test2
 if "%2" == "tiered"    goto test2
@@ -70,6 +74,7 @@
 goto usage
 
 :test2
+if "%1" == "tree"      goto build_tree
 REM check_j2se_version
 REM jvmti.make requires J2SE 1.4.x or newer.
 REM If not found then fail fast.
@@ -93,6 +98,10 @@
 nmake -f %3/make/windows/build.make Variant=compiler2 WorkSpace=%3 BootStrapDir=%4 BuildUser="%USERNAME%" HOTSPOT_BUILD_VERSION=%5 ADLC_ONLY=1 %1
 goto end
 
+:build_tree
+nmake -f %3/make/windows/build.make Variant=%2 WorkSpace=%3 BootStrapDir=%4 BuildUser="%USERNAME%" HOTSPOT_BUILD_VERSION="%5" %1
+goto end
+
 :usage
 echo Usage: build flavor version workspace bootstrap_dir [build_id] [windbg_home]
 echo.
@@ -100,8 +109,10 @@
 echo flavor is "product", "debug" or "fastdebug",
 echo version is "core", "kernel", "compiler1", "compiler2", or "tiered",
 echo workspace is source directory without trailing slash, 
-echo bootstrap_dir is a full path to echo a JDK in which bin/java 
-echo   and bin/javac are present and working, and echo build_id is an 
+echo bootstrap_dir is a full path to a JDK in which bin/java 
+echo   and bin/javac are present and working, and build_id is an 
 echo   optional build identifier displayed by java -version
+exit /b 1
 
 :end
+exit /b %errorlevel%
--- a/make/windows/build.make	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/windows/build.make	Mon Apr 19 20:41:10 2010 -0700
@@ -27,6 +27,9 @@
 # environment variables (Variant, WorkSpace, BootStrapDir, BuildUser, HOTSPOT_BUILD_VERSION)
 # are passed in as command line arguments.
 
+# Note: Running nmake or build.bat from the Windows command shell requires
+# that "sh" be accessible on the PATH. An MKS install does this.
+
 # SA components are built if BUILD_WIN_SA=1 is specified.
 # See notes in README. This produces files:
 #  1. sa-jdi.jar       - This is built before building jvm.dll
@@ -233,6 +236,12 @@
 	cd $(variantDir)
 	nmake -nologo -f $(WorkSpace)\make\windows\makefiles\top.make BUILD_FLAVOR=product DEVELOP=1 ARCH=$(ARCH)
 
+# target to create just the directory structure
+tree: checks $(variantDir) $(variantDir)\local.make sanity
+	mkdir $(variantDir)\product
+	mkdir $(variantDir)\debug
+	mkdir $(variantDir)\fastdebug
+
 sanity:
 	@ echo;
 	@ cd $(variantDir)
--- a/make/windows/create.bat	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/windows/create.bat	Mon Apr 19 20:41:10 2010 -0700
@@ -36,6 +36,9 @@
 REM Since we don't have uname and we could be cross-compiling,
 REM Use the compiler to determine which ARCH we are building
 REM 
+REM Note: Running this batch file from the Windows command shell requires
+REM that "grep" be accessible on the PATH. An MKS install does this.
+REM 
 cl 2>&1 | grep "IA-64" >NUL
 if %errorlevel% == 0 goto isia64
 cl 2>&1 | grep "AMD64" >NUL
--- a/make/windows/get_msc_ver.sh	Sat Mar 20 11:12:00 2010 -0700
+++ b/make/windows/get_msc_ver.sh	Mon Apr 19 20:41:10 2010 -0700
@@ -22,6 +22,8 @@
 #  
 #
 
+set -e
+
 # This shell script echoes "MSC_VER=<munged version of cl>"
 # It ignores the micro version component.
 # Examples:
@@ -38,17 +40,20 @@
 # sh, and it has been found that sometimes `which sh` fails.
 
 if [ "x$HotSpotMksHome" != "x" ]; then
- MKS_HOME="$HotSpotMksHome"
+  TOOL_DIR="$HotSpotMksHome"
 else
- SH=`which sh`
- MKS_HOME=`dirname "$SH"`
+  # HotSpotMksHome is not set so use the directory that contains "sh".
+  # This works with both MKS and Cygwin.
+  SH=`which sh`
+  TOOL_DIR=`dirname "$SH"`
 fi
 
-HEAD="$MKS_HOME/head"
-ECHO="$MKS_HOME/echo"
-EXPR="$MKS_HOME/expr"
-CUT="$MKS_HOME/cut"
-SED="$MKS_HOME/sed"
+DIRNAME="$TOOL_DIR/dirname"
+HEAD="$TOOL_DIR/head"
+ECHO="$TOOL_DIR/echo"
+EXPR="$TOOL_DIR/expr"
+CUT="$TOOL_DIR/cut"
+SED="$TOOL_DIR/sed"
 
 if [ "x$FORCE_MSC_VER" != "x" ]; then
   echo "MSC_VER=$FORCE_MSC_VER"
@@ -70,7 +75,15 @@
 if [ "x$FORCE_LINK_VER" != "x" ]; then
   echo "LINK_VER=$FORCE_LINK_VER"
 else
-  LINK_VER_RAW=`link 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'`
+  # use the "link" command that is co-located with the "cl" command
+  cl_cmd=`which cl`
+  if [ "x$cl_cmd" != "x" ]; then
+    link_cmd=`$DIRNAME "$cl_cmd"`/link
+  else
+    # which can't find "cl" so just use which ever "link" we find
+    link_cmd="link"
+  fi
+  LINK_VER_RAW=`"$link_cmd" 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'`
   LINK_VER_MAJOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f1`
   LINK_VER_MINOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f2`
   LINK_VER_MICRO=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f3`
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -377,6 +377,16 @@
 
 }
 
+
+void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  __ call(SharedRuntime::deopt_blob()->unpack_with_reexecution());
+  __ delayed()->nop();
+  ce->add_call_info_here(_info);
+  debug_only(__ should_not_reach_here());
+}
+
+
 void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
   //---------------slow case: call to native-----------------
   __ bind(_entry);
--- a/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/c1_FrameMap_sparc.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -143,3 +143,6 @@
 
   static bool is_caller_save_register (LIR_Opr  reg);
   static bool is_caller_save_register (Register r);
+
+  // JSR 292
+  static LIR_Opr& method_handle_invoke_SP_save_opr() { return L7_opr; }
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -378,12 +378,7 @@
 
   int offset = code_offset();
 
-  if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
-    __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
-    __ delayed()->nop();
-  }
-
-  __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type);
+  __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
   __ delayed()->nop();
   debug_only(__ stop("should have gone to the caller");)
   assert(code_offset() - offset <= exception_handler_size, "overflow");
@@ -685,29 +680,29 @@
 }
 
 
-void LIR_Assembler::call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info) {
-  __ call(entry, rtype);
+void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
+  __ call(op->addr(), rtype);
   // the peephole pass fills the delay slot
 }
 
 
-void LIR_Assembler::ic_call(address entry, CodeEmitInfo* info) {
+void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
   RelocationHolder rspec = virtual_call_Relocation::spec(pc());
   __ set_oop((jobject)Universe::non_oop_word(), G5_inline_cache_reg);
   __ relocate(rspec);
-  __ call(entry, relocInfo::none);
+  __ call(op->addr(), relocInfo::none);
   // the peephole pass fills the delay slot
 }
 
 
-void LIR_Assembler::vtable_call(int vtable_offset, CodeEmitInfo* info) {
-  add_debug_info_for_null_check_here(info);
+void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
+  add_debug_info_for_null_check_here(op->info());
   __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
-  if (__ is_simm13(vtable_offset) ) {
-    __ ld_ptr(G3_scratch, vtable_offset, G5_method);
+  if (__ is_simm13(op->vtable_offset())) {
+    __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method);
   } else {
     // This will generate 2 instructions
-    __ set(vtable_offset, G5_method);
+    __ set(op->vtable_offset(), G5_method);
     // ld_ptr, set_hi, set
     __ ld_ptr(G3_scratch, G5_method, G5_method);
   }
@@ -717,6 +712,16 @@
 }
 
 
+void LIR_Assembler::preserve_SP(LIR_OpJavaCall* op) {
+  Unimplemented();
+}
+
+
+void LIR_Assembler::restore_SP(LIR_OpJavaCall* op) {
+  Unimplemented();
+}
+
+
 // load with 32-bit displacement
 int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) {
   int load_offset = code_offset();
@@ -1067,7 +1072,8 @@
   LIR_Const* c = src->as_constant_ptr();
   switch (c->type()) {
     case T_INT:
-    case T_FLOAT: {
+    case T_FLOAT:
+    case T_ADDRESS: {
       Register src_reg = O7;
       int value = c->as_jint_bits();
       if (value == 0) {
@@ -1123,7 +1129,8 @@
   }
   switch (c->type()) {
     case T_INT:
-    case T_FLOAT: {
+    case T_FLOAT:
+    case T_ADDRESS: {
       LIR_Opr tmp = FrameMap::O7_opr;
       int value = c->as_jint_bits();
       if (value == 0) {
@@ -1195,6 +1202,7 @@
 
   switch (c->type()) {
     case T_INT:
+    case T_ADDRESS:
       {
         jint con = c->as_jint();
         if (to_reg->is_single_cpu()) {
--- a/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -42,17 +42,6 @@
 }
 
 
-void C1_MacroAssembler::method_exit(bool restore_frame) {
-  // this code must be structured this way so that the return
-  // instruction can be a safepoint.
-  if (restore_frame) {
-    restore();
-  }
-  retl();
-  delayed()->nop();
-}
-
-
 void C1_MacroAssembler::explicit_null_check(Register base) {
   Unimplemented();
 }
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -677,7 +677,7 @@
         __ add(I7, frame::pc_return_offset, Oissuing_pc->after_save());
 
         __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
-                        Oissuing_pc->after_save());
+                        G2_thread, Oissuing_pc->after_save());
         __ verify_not_null_oop(Oexception->after_save());
         __ jmp(O0, 0);
         __ delayed()->restore();
@@ -985,7 +985,6 @@
 
 void Runtime1::generate_handle_exception(StubAssembler* sasm, OopMapSet* oop_maps, OopMap* oop_map, bool) {
   Label no_deopt;
-  Label no_handler;
 
   __ verify_not_null_oop(Oexception);
 
@@ -1003,9 +1002,14 @@
   // whether it had a handler or not we will deoptimize
   // by entering the deopt blob with a pending exception.
 
+#ifdef ASSERT
+  Label done;
   __ tst(O0);
-  __ br(Assembler::zero, false, Assembler::pn, no_handler);
+  __ br(Assembler::notZero, false, Assembler::pn, done);
   __ delayed()->nop();
+  __ stop("should have found address");
+  __ bind(done);
+#endif
 
   // restore the registers that were saved at the beginning and jump to the exception handler.
   restore_live_registers(sasm);
@@ -1013,20 +1017,6 @@
   __ jmp(O0, 0);
   __ delayed()->restore();
 
-  __ bind(no_handler);
-  __ mov(L0, I7); // restore return address
-
-  // restore exception oop
-  __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), Oexception->after_save());
-  __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
-
-  __ restore();
-
-  AddressLiteral exc(Runtime1::entry_for(Runtime1::unwind_exception_id));
-  __ jump_to(exc, G4);
-  __ delayed()->nop();
-
-
   oop_maps->add_gc_map(call_offset, oop_map);
 }
 
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -244,9 +244,10 @@
 }
 
 
-void InterpreterMacroAssembler::super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1) {
+void InterpreterMacroAssembler::super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2) {
   mov(arg_1, O0);
-  MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 1);
+  mov(arg_2, O1);
+  MacroAssembler::call_VM_leaf_base(thread_cache, entry_point, 2);
 }
 #endif /* CC_INTERP */
 
--- a/src/cpu/sparc/vm/interp_masm_sparc.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -121,7 +121,7 @@
                      bool check_exception = true);
 
 #ifndef CC_INTERP
-  void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1);
+  void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2);
 
   // Generate a subtype check: branch to ok_is_subtype if sub_klass is
   // a subtype of super_klass.  Blows registers tmp1, tmp2 and tmp3.
--- a/src/cpu/sparc/vm/sparc.ad	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/sparc.ad	Mon Apr 19 20:41:10 2010 -0700
@@ -1803,8 +1803,9 @@
 // to implement the UseStrictFP mode.
 const bool Matcher::strict_fp_requires_explicit_rounding = false;
 
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = false;
+// Are floats conerted to double when stored to stack during deoptimization?
+// Sparc does not handle callee-save floats.
+bool Matcher::float_in_double() { return false; }
 
 // Do ints take an entire long register or just half?
 // Note that we if-def off of _LP64.
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -379,7 +379,7 @@
     __ save_frame(0);             // compensates for compiler weakness
     __ add(O7->after_save(), frame::pc_return_offset, Lscratch); // save the issuing PC
     BLOCK_COMMENT("call exception_handler_for_return_address");
-    __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), Lscratch);
+    __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), G2_thread, Lscratch);
     __ mov(O0, handler_reg);
     __ restore();                 // compensates for compiler weakness
 
--- a/src/cpu/sparc/vm/stubRoutines_sparc.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/stubRoutines_sparc.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -37,8 +37,13 @@
 
 enum /* platform_dependent_constants */ {
   // %%%%%%%% May be able to shrink this a lot
-  code_size1 = 20000,                                        // simply increase if too small (assembler will crash if too small)
-  code_size2 = 20000                                         // simply increase if too small (assembler will crash if too small)
+  code_size1 = 20000,           // simply increase if too small (assembler will crash if too small)
+  code_size2 = 20000            // simply increase if too small (assembler will crash if too small)
+};
+
+// MethodHandles adapters
+enum method_handles_platform_dependent_constants {
+  method_handles_adapters_code_size = 5000
 };
 
 class Sparc {
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -1822,7 +1822,7 @@
   __ add(issuing_pc_addr, Oissuing_pc->after_save());  // likewise set I1 to a value local to the caller
   __ super_call_VM_leaf(L7_thread_cache,
                         CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
-                        Oissuing_pc->after_save());
+                        G2_thread, Oissuing_pc->after_save());
 
   // The caller's SP was adjusted upon method entry to accomodate
   // the callee's non-argument locals. Undo that adjustment.
--- a/src/cpu/x86/vm/assembler_x86.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -8460,6 +8460,7 @@
   subptr(str1, result); // Restore counter
   shrl(str1, 1);
   addl(cnt1, str1);
+  decrementl(cnt1);
   lea(str1, Address(result, 2)); // Reload string
 
   // Load substr
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -373,6 +373,14 @@
 }
 
 
+void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  __ call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack_with_reexecution()));
+  ce->add_call_info_here(_info);
+  debug_only(__ should_not_reach_here());
+}
+
+
 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
   __ bind(_entry);
--- a/src/cpu/x86/vm/c1_FrameMap_x86.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/c1_FrameMap_x86.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -126,3 +126,6 @@
     assert(i >= 0 && i < nof_caller_save_xmm_regs, "out of bounds");
     return _caller_save_xmm_regs[i];
   }
+
+  // JSR 292
+  static LIR_Opr& method_handle_invoke_SP_save_opr() { return rbp_opr; }
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -436,40 +436,18 @@
 
   int offset = code_offset();
 
-  // if the method does not have an exception handler, then there is
-  // no reason to search for one
-  if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
-    // the exception oop and pc are in rax, and rdx
-    // no other registers need to be preserved, so invalidate them
-    __ invalidate_registers(false, true, true, false, true, true);
-
-    // check that there is really an exception
-    __ verify_not_null_oop(rax);
-
-    // search an exception handler (rax: exception oop, rdx: throwing pc)
-    __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
-
-    // if the call returns here, then the exception handler for particular
-    // exception doesn't exist -> unwind activation and forward exception to caller
-  }
-
-  // the exception oop is in rax,
+  // the exception oop and pc are in rax, and rdx
   // no other registers need to be preserved, so invalidate them
-  __ invalidate_registers(false, true, true, true, true, true);
+  __ invalidate_registers(false, true, true, false, true, true);
 
   // check that there is really an exception
   __ verify_not_null_oop(rax);
 
-  // unlock the receiver/klass if necessary
-  // rax,: exception
-  ciMethod* method = compilation()->method();
-  if (method->is_synchronized() && GenerateSynchronizationCode) {
-    monitorexit(FrameMap::rbx_oop_opr, FrameMap::rcx_opr, SYNC_header, 0, rax);
-  }
-
-  // unwind activation and forward exception to caller
-  // rax,: exception
-  __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
+  // search an exception handler (rax: exception oop, rdx: throwing pc)
+  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
+
+  __ stop("should not reach here");
+
   assert(code_offset() - offset <= exception_handler_size, "overflow");
   __ end_a_stub();
 
@@ -495,8 +473,10 @@
 
   int offset = code_offset();
   InternalAddress here(__ pc());
+
   __ pushptr(here.addr());
   __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
+
   assert(code_offset() - offset <= deopt_handler_size, "overflow");
   __ end_a_stub();
 
@@ -593,7 +573,7 @@
   }
 
   // Pop the stack before the safepoint code
-  __ leave();
+  __ remove_frame(initial_frame_size_in_bytes());
 
   bool result_is_oop = result->is_valid() ? result->is_oop() : false;
 
@@ -648,7 +628,8 @@
   LIR_Const* c = src->as_constant_ptr();
 
   switch (c->type()) {
-    case T_INT: {
+    case T_INT:
+    case T_ADDRESS: {
       assert(patch_code == lir_patch_none, "no patching handled here");
       __ movl(dest->as_register(), c->as_jint());
       break;
@@ -731,6 +712,7 @@
   switch (c->type()) {
     case T_INT:  // fall through
     case T_FLOAT:
+    case T_ADDRESS:
       __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
       break;
 
@@ -766,6 +748,7 @@
   switch (type) {
     case T_INT:    // fall through
     case T_FLOAT:
+    case T_ADDRESS:
       __ movl(as_Address(addr), c->as_jint_bits());
       break;
 
@@ -2738,6 +2721,7 @@
     switch (code) {
       case lir_static_call:
       case lir_optvirtual_call:
+      case lir_dynamic_call:
         offset += NativeCall::displacement_offset;
         break;
       case lir_icvirtual_call:
@@ -2753,30 +2737,41 @@
 }
 
 
-void LIR_Assembler::call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info) {
+void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
   assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
          "must be aligned");
-  __ call(AddressLiteral(entry, rtype));
-  add_call_info(code_offset(), info);
+  __ call(AddressLiteral(op->addr(), rtype));
+  add_call_info(code_offset(), op->info(), op->is_method_handle_invoke());
 }
 
 
-void LIR_Assembler::ic_call(address entry, CodeEmitInfo* info) {
+void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
   RelocationHolder rh = virtual_call_Relocation::spec(pc());
   __ movoop(IC_Klass, (jobject)Universe::non_oop_word());
   assert(!os::is_MP() ||
          (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
          "must be aligned");
-  __ call(AddressLiteral(entry, rh));
-  add_call_info(code_offset(), info);
+  __ call(AddressLiteral(op->addr(), rh));
+  add_call_info(code_offset(), op->info(), op->is_method_handle_invoke());
 }
 
 
 /* Currently, vtable-dispatch is only enabled for sparc platforms */
-void LIR_Assembler::vtable_call(int vtable_offset, CodeEmitInfo* info) {
+void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
   ShouldNotReachHere();
 }
 
+
+void LIR_Assembler::preserve_SP(LIR_OpJavaCall* op) {
+  __ movptr(FrameMap::method_handle_invoke_SP_save_opr()->as_register(), rsp);
+}
+
+
+void LIR_Assembler::restore_SP(LIR_OpJavaCall* op) {
+  __ movptr(rsp, FrameMap::method_handle_invoke_SP_save_opr()->as_register());
+}
+
+
 void LIR_Assembler::emit_static_call_stub() {
   address call_pc = __ pc();
   address stub = __ start_a_stub(call_stub_size);
@@ -2829,10 +2824,12 @@
     } else {
       unwind_id = Runtime1::handle_exception_nofpu_id;
     }
+    __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
   } else {
-    unwind_id = Runtime1::unwind_exception_id;
+    // remove the activation
+    __ remove_frame(initial_frame_size_in_bytes());
+    __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
   }
-  __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
 
   // enough room for two byte trap
   __ nop();
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -317,14 +317,6 @@
 }
 
 
-void C1_MacroAssembler::method_exit(bool restore_frame) {
-  if (restore_frame) {
-    leave();
-  }
-  ret(0);
-}
-
-
 void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
   // Make sure there is enough stack space for this method's activation.
   // Note that we do this before doing an enter(). This matches the
@@ -333,7 +325,7 @@
   // between the two compilers.
   generate_stack_overflow_check(frame_size_in_bytes);
 
-  enter();
+  push(rbp);
 #ifdef TIERED
   // c2 leaves fpu stack dirty. Clean it on entry
   if (UseSSE < 2 ) {
@@ -344,6 +336,12 @@
 }
 
 
+void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
+  increment(rsp, frame_size_in_bytes);  // Does not emit code for frame_size == 0
+  pop(rbp);
+}
+
+
 void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) {
   if (C1Breakpoint) int3();
   inline_cache_check(receiver, ic_klass);
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -688,18 +688,21 @@
   int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
   oop_maps->add_gc_map(call_offset, oop_map);
 
-  // rax,: handler address or NULL if no handler exists
+  // rax,: handler address
   //      will be the deopt blob if nmethod was deoptimized while we looked up
   //      handler regardless of whether handler existed in the nmethod.
 
   // only rax, is valid at this time, all other registers have been destroyed by the runtime call
   __ invalidate_registers(false, true, true, true, true, true);
 
+#ifdef ASSERT
   // Do we have an exception handler in the nmethod?
-  Label no_handler;
   Label done;
   __ testptr(rax, rax);
-  __ jcc(Assembler::zero, no_handler);
+  __ jcc(Assembler::notZero, done);
+  __ stop("no handler found");
+  __ bind(done);
+#endif
 
   // exception handler found
   // patch the return address -> the stub will directly return to the exception handler
@@ -712,36 +715,14 @@
   __ leave();
   __ ret(0);
 
-  __ bind(no_handler);
-  // no exception handler found in this method, so the exception is
-  // forwarded to the caller (using the unwind code of the nmethod)
-  // there is no need to restore the registers
-
-  // restore the real return address that was saved before the RT-call
-  __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size));
-  __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr);
-
-  // load address of JavaThread object for thread-local data
-  NOT_LP64(__ get_thread(thread);)
-  // restore exception oop into rax, (convention for unwind code)
-  __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset()));
-
-  // clear exception fields in JavaThread because they are no longer needed
-  // (fields must be cleared because they are processed by GC otherwise)
-  __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD);
-  __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD);
-
-  // pop the stub frame off
-  __ leave();
-
-  generate_unwind_exception(sasm);
-  __ stop("should not reach here");
 }
 
 
 void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
   // incoming parameters
   const Register exception_oop = rax;
+  // callee-saved copy of exception_oop during runtime call
+  const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14);
   // other registers used in this stub
   const Register exception_pc = rdx;
   const Register handler_addr = rbx;
@@ -769,38 +750,39 @@
   // clear the FPU stack in case any FPU results are left behind
   __ empty_FPU_stack();
 
-  // leave activation of nmethod
-  __ leave();
-  // store return address (is on top of stack after leave)
+  // save exception_oop in callee-saved register to preserve it during runtime calls
+  __ verify_not_null_oop(exception_oop);
+  __ movptr(exception_oop_callee_saved, exception_oop);
+
+  NOT_LP64(__ get_thread(thread);)
+  // Get return address (is on top of stack after leave).
   __ movptr(exception_pc, Address(rsp, 0));
 
-  __ verify_oop(exception_oop);
+  // search the exception handler address of the caller (using the return address)
+  __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
+  // rax: exception handler address of the caller
 
-  // save exception oop from rax, to stack before call
-  __ push(exception_oop);
-
-  // search the exception handler address of the caller (using the return address)
-  __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc);
-  // rax,: exception handler address of the caller
-
-  // only rax, is valid at this time, all other registers have been destroyed by the call
-  __ invalidate_registers(false, true, true, true, true, true);
+  // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call.
+  __ invalidate_registers(false, true, true, true, false, true);
 
   // move result of call into correct register
   __ movptr(handler_addr, rax);
 
-  // restore exception oop in rax, (required convention of exception handler)
-  __ pop(exception_oop);
+  // Restore exception oop to RAX (required convention of exception handler).
+  __ movptr(exception_oop, exception_oop_callee_saved);
 
-  __ verify_oop(exception_oop);
+  // verify that there is really a valid exception in rax
+  __ verify_not_null_oop(exception_oop);
 
   // get throwing pc (= return address).
   // rdx has been destroyed by the call, so it must be set again
   // the pop is also necessary to simulate the effect of a ret(0)
   __ pop(exception_pc);
 
-  // verify that that there is really a valid exception in rax,
-  __ verify_not_null_oop(exception_oop);
+  // Restore SP from BP if the exception PC is a MethodHandle call site.
+  NOT_LP64(__ get_thread(thread);)
+  __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0);
+  __ cmovptr(Assembler::notEqual, rsp, rbp);
 
   // continue at exception handler (return address removed)
   // note: do *not* remove arguments when unwinding the
@@ -808,9 +790,9 @@
   //       all arguments on the stack when entering the
   //       runtime to determine the exception handler
   //       (GC happens at call site with arguments!)
-  // rax,: exception oop
+  // rax: exception oop
   // rdx: throwing pc
-  // rbx,: exception handler
+  // rbx: exception handler
   __ jmp(handler_addr);
 }
 
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -60,13 +60,13 @@
 }
 
 #ifdef ASSERT
-static void verify_argslot(MacroAssembler* _masm, Register rax_argslot,
+static void verify_argslot(MacroAssembler* _masm, Register argslot_reg,
                            const char* error_message) {
   // Verify that argslot lies within (rsp, rbp].
   Label L_ok, L_bad;
-  __ cmpptr(rax_argslot, rbp);
+  __ cmpptr(argslot_reg, rbp);
   __ jccb(Assembler::above, L_bad);
-  __ cmpptr(rsp, rax_argslot);
+  __ cmpptr(rsp, argslot_reg);
   __ jccb(Assembler::below, L_ok);
   __ bind(L_bad);
   __ stop(error_message);
@@ -178,22 +178,6 @@
 
   // Now move the argslot down, to point to the opened-up space.
   __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr));
-
-  if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) {
-    // The caller has specified a bitmask of tags to put into the opened space.
-    // This only works when the arg_slots value is an assembly-time constant.
-    int constant_arg_slots = arg_slots.as_constant() / stack_move_unit();
-    int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
-    for (int slot = 0; slot < constant_arg_slots; slot++) {
-      BasicType slot_type   = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT);
-      int       slot_offset = Interpreter::stackElementSize() * slot;
-      Address   tag_addr(rax_argslot, slot_offset + tag_offset);
-      __ movptr(tag_addr, frame::tag_for_basic_type(slot_type));
-    }
-    // Note that the new argument slots are tagged properly but contain
-    // garbage at this point.  The value portions must be initialized
-    // by the caller.  (Especially references!)
-  }
 }
 
 // Helper to remove argument slots from the stack.
@@ -206,18 +190,9 @@
                              (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
 
 #ifdef ASSERT
-  {
-    // Verify that [argslot..argslot+size) lies within (rsp, rbp).
-    Label L_ok, L_bad;
-    __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
-    __ cmpptr(rbx_temp, rbp);
-    __ jccb(Assembler::above, L_bad);
-    __ cmpptr(rsp, rax_argslot);
-    __ jccb(Assembler::below, L_ok);
-    __ bind(L_bad);
-    __ stop("deleted argument(s) must fall within current frame");
-    __ bind(L_ok);
-  }
+  // Verify that [argslot..argslot+size) lies within (rsp, rbp).
+  __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr));
+  verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame");
   if (arg_slots.is_register()) {
     Label L_ok, L_bad;
     __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
@@ -321,12 +296,6 @@
   Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
   Address vmarg;                // __ argument_address(vmargslot)
 
-  int tag_offset = -1;
-  if (TaggedStackInterpreter) {
-    tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
-    assert(tag_offset = wordSize, "stack grows as expected");
-  }
-
   const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
 
   if (have_entry(ek)) {
@@ -372,11 +341,8 @@
       __ mov(rsp, rsi);   // cut the stack back to where the caller started
 
       // Repush the arguments as if coming from the interpreter.
-      if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_INT));
       __ push(rdx_code);
-      if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_OBJECT));
       __ push(rcx_fail);
-      if (TaggedStackInterpreter)  __ push(frame::tag_for_basic_type(T_OBJECT));
       __ push(rax_want);
 
       Register rbx_method = rbx_temp;
@@ -397,7 +363,6 @@
       // Do something that is at least causes a valid throw from the interpreter.
       __ bind(no_method);
       __ pop(rax_want);
-      if (TaggedStackInterpreter)  __ pop(rcx_fail);
       __ pop(rcx_fail);
       __ push(rax_want);
       __ push(rcx_fail);
@@ -510,18 +475,10 @@
   case _bound_long_direct_mh:
     {
       bool direct_to_method = (ek >= _bound_ref_direct_mh);
-      BasicType arg_type = T_ILLEGAL;
-      if (ek == _bound_long_mh || ek == _bound_long_direct_mh) {
-        arg_type = T_LONG;
-      } else if (ek == _bound_int_mh || ek == _bound_int_direct_mh) {
-        arg_type = T_INT;
-      } else {
-        assert(ek == _bound_ref_mh || ek == _bound_ref_direct_mh, "must be ref");
-        arg_type = T_OBJECT;
-      }
-      int arg_slots = type2size[arg_type];
-      int arg_mask  = (arg_type == T_OBJECT ? _INSERT_REF_MASK :
-                       arg_slots == 1       ? _INSERT_INT_MASK :  _INSERT_LONG_MASK);
+      BasicType arg_type  = T_ILLEGAL;
+      int       arg_mask  = _INSERT_NO_MASK;
+      int       arg_slots = -1;
+      get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots);
 
       // make room for the new argument:
       __ movl(rax_argslot, rcx_bmh_vmargslot);
@@ -584,7 +541,7 @@
 
       Label done;
       __ movptr(rdx_temp, vmarg);
-      __ testl(rdx_temp, rdx_temp);
+      __ testptr(rdx_temp, rdx_temp);
       __ jccb(Assembler::zero, done);         // no cast if null
       __ load_klass(rdx_temp, rdx_temp);
 
@@ -660,13 +617,10 @@
         }
         break;
       default:
-        assert(false, "");
+        ShouldNotReachHere();
       }
-      goto finish_int_conversion;
-    }
 
-  finish_int_conversion:
-    {
+      // Do the requested conversion and store the value.
       Register rbx_vminfo = rbx_temp;
       __ movl(rbx_vminfo, rcx_amh_conversion);
       assert(CONV_VMINFO_SHIFT == 0, "preshifted");
@@ -692,7 +646,7 @@
       __ shrl(rdx_temp /*, rcx*/);
 
       __ bind(done);
-      __ movl(vmarg, rdx_temp);
+      __ movl(vmarg, rdx_temp);  // Store the value.
       __ xchgptr(rcx, rbx_vminfo);                // restore rcx_recv
 
       __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
@@ -715,9 +669,14 @@
       switch (ek) {
       case _adapter_opt_i2l:
         {
+#ifdef _LP64
+          __ movslq(rdx_temp, vmarg1);  // Load sign-extended
+          __ movq(vmarg1, rdx_temp);    // Store into first slot
+#else
           __ movl(rdx_temp, vmarg1);
-          __ sarl(rdx_temp, 31);  // __ extend_sign()
+          __ sarl(rdx_temp, BitsPerInt - 1);  // __ extend_sign()
           __ movl(vmarg2, rdx_temp); // store second word
+#endif
         }
         break;
       case _adapter_opt_unboxl:
@@ -727,14 +686,19 @@
           int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_LONG);
           assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), "");
           __ null_check(rdx_temp, value_offset);
+#ifdef _LP64
+          __ movq(rbx_temp, Address(rdx_temp, value_offset));
+          __ movq(vmarg1, rbx_temp);
+#else
           __ movl(rbx_temp, Address(rdx_temp, value_offset + 0*BytesPerInt));
           __ movl(rdx_temp, Address(rdx_temp, value_offset + 1*BytesPerInt));
           __ movl(vmarg1, rbx_temp);
           __ movl(vmarg2, rdx_temp);
+#endif
         }
         break;
       default:
-        assert(false, "");
+        ShouldNotReachHere();
       }
 
       __ movptr(rcx_recv, rcx_mh_vmtarget);
@@ -768,20 +732,9 @@
       if (ek == _adapter_opt_f2d) {
         __ fld_s(vmarg);        // load float to ST0
         __ fstp_s(vmarg);       // store single
-      } else if (!TaggedStackInterpreter) {
+      } else {
         __ fld_d(vmarg);        // load double to ST0
         __ fstp_s(vmarg);       // store single
-      } else {
-        Address vmarg_tag = vmarg.plus_disp(tag_offset);
-        Address vmarg2    = vmarg.plus_disp(Interpreter::stackElementSize());
-        // vmarg2_tag does not participate in this code
-        Register rbx_tag = rbx_temp;
-        __ movl(rbx_tag, vmarg_tag); // preserve tag
-        __ movl(rdx_temp, vmarg2); // get second word of double
-        __ movl(vmarg_tag, rdx_temp); // align with first word
-        __ fld_d(vmarg);        // load double to ST0
-        __ movl(vmarg_tag, rbx_tag); // restore tag
-        __ fstp_s(vmarg);       // store single
       }
 #endif //_LP64
 
@@ -812,19 +765,8 @@
   case _adapter_opt_rot_2_up:
   case _adapter_opt_rot_2_down:
     {
-      int rotate = 0, swap_slots = 0;
-      switch ((int)ek) {
-      case _adapter_opt_swap_1:     swap_slots = 1; break;
-      case _adapter_opt_swap_2:     swap_slots = 2; break;
-      case _adapter_opt_rot_1_up:   swap_slots = 1; rotate++; break;
-      case _adapter_opt_rot_1_down: swap_slots = 1; rotate--; break;
-      case _adapter_opt_rot_2_up:   swap_slots = 2; rotate++; break;
-      case _adapter_opt_rot_2_down: swap_slots = 2; rotate--; break;
-      default: assert(false, "");
-      }
-
-      // the real size of the move must be doubled if TaggedStackInterpreter:
-      int swap_bytes = (int)( swap_slots * Interpreter::stackElementWords() * wordSize );
+      int swap_bytes = 0, rotate = 0;
+      get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate);
 
       // 'argslot' is the position of the first argument to swap
       __ movl(rax_argslot, rcx_amh_vmargslot);
@@ -925,8 +867,8 @@
 
       // 'stack_move' is negative number of words to duplicate
       Register rdx_stack_move = rdx_temp;
-      __ movl(rdx_stack_move, rcx_amh_conversion);
-      __ sarl(rdx_stack_move, CONV_STACK_MOVE_SHIFT);
+      __ movl2ptr(rdx_stack_move, rcx_amh_conversion);
+      __ sarptr(rdx_stack_move, CONV_STACK_MOVE_SHIFT);
 
       int argslot0_num = 0;
       Address argslot0 = __ argument_address(RegisterOrConstant(argslot0_num));
@@ -988,8 +930,8 @@
 
       // 'stack_move' is number of words to drop
       Register rdi_stack_move = rdi;
-      __ movl(rdi_stack_move, rcx_amh_conversion);
-      __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
+      __ movl2ptr(rdi_stack_move, rcx_amh_conversion);
+      __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
       remove_arg_slots(_masm, rdi_stack_move,
                        rax_argslot, rbx_temp, rdx_temp);
 
@@ -1014,11 +956,7 @@
   case _adapter_opt_spread_more:
     {
       // spread an array out into a group of arguments
-      int length_constant = -1;
-      switch (ek) {
-      case _adapter_opt_spread_0: length_constant = 0; break;
-      case _adapter_opt_spread_1: length_constant = 1; break;
-      }
+      int length_constant = get_ek_adapter_opt_spread_info(ek);
 
       // find the address of the array argument
       __ movl(rax_argslot, rcx_amh_vmargslot);
@@ -1079,8 +1017,8 @@
         __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize()));
         // 'stack_move' is negative number of words to insert
         Register rdi_stack_move = rdi;
-        __ movl(rdi_stack_move, rcx_amh_conversion);
-        __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
+        __ movl2ptr(rdi_stack_move, rcx_amh_conversion);
+        __ sarptr(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
         Register rsi_temp = rsi_array;  // spill this
         insert_arg_slots(_masm, rdi_stack_move, -1,
                          rax_argslot, rbx_temp, rsi_temp);
@@ -1114,10 +1052,6 @@
         __ movptr(rbx_temp, Address(rsi_source, 0));
         __ movptr(Address(rax_argslot, 0), rbx_temp);
         __ addptr(rsi_source, type2aelembytes(elem_type));
-        if (TaggedStackInterpreter) {
-          __ movptr(Address(rax_argslot, tag_offset),
-                    frame::tag_for_basic_type(elem_type));
-        }
         __ addptr(rax_argslot, Interpreter::stackElementSize());
         __ cmpptr(rax_argslot, rdx_argslot_limit);
         __ jccb(Assembler::less, loop);
@@ -1131,11 +1065,7 @@
           __ movptr(rbx_temp, Address(rsi_array, elem_offset));
           __ movptr(Address(rax_argslot, slot_offset), rbx_temp);
           elem_offset += type2aelembytes(elem_type);
-          if (TaggedStackInterpreter) {
-            __ movptr(Address(rax_argslot, slot_offset + tag_offset),
-                      frame::tag_for_basic_type(elem_type));
-          }
-          slot_offset += Interpreter::stackElementSize();
+           slot_offset += Interpreter::stackElementSize();
         }
       }
 
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -369,7 +369,7 @@
   // The pending exception in Thread is converted into a Java-level exception.
   //
   // Contract with Java-level exception handlers:
-  // rax,: exception
+  // rax: exception
   // rdx: throwing pc
   //
   // NOTE: At entry of this stub, exception-pc must be on stack !!
@@ -377,6 +377,12 @@
   address generate_forward_exception() {
     StubCodeMark mark(this, "StubRoutines", "forward exception");
     address start = __ pc();
+    const Register thread = rcx;
+
+    // other registers used in this stub
+    const Register exception_oop = rax;
+    const Register handler_addr  = rbx;
+    const Register exception_pc  = rdx;
 
     // Upon entry, the sp points to the return address returning into Java
     // (interpreted or compiled) code; i.e., the return address becomes the
@@ -389,8 +395,8 @@
 #ifdef ASSERT
     // make sure this code is only executed if there is a pending exception
     { Label L;
-      __ get_thread(rcx);
-      __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
+      __ get_thread(thread);
+      __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
       __ jcc(Assembler::notEqual, L);
       __ stop("StubRoutines::forward exception: no pending exception (1)");
       __ bind(L);
@@ -398,33 +404,40 @@
 #endif
 
     // compute exception handler into rbx,
-    __ movptr(rax, Address(rsp, 0));
+    __ get_thread(thread);
+    __ movptr(exception_pc, Address(rsp, 0));
     BLOCK_COMMENT("call exception_handler_for_return_address");
-    __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax);
-    __ mov(rbx, rax);
+    __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
+    __ mov(handler_addr, rax);
 
-    // setup rax, & rdx, remove return address & clear pending exception
-    __ get_thread(rcx);
-    __ pop(rdx);
-    __ movptr(rax, Address(rcx, Thread::pending_exception_offset()));
-    __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD);
+    // setup rax & rdx, remove return address & clear pending exception
+    __ get_thread(thread);
+    __ pop(exception_pc);
+    __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
+    __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
 
 #ifdef ASSERT
     // make sure exception is set
     { Label L;
-      __ testptr(rax, rax);
+      __ testptr(exception_oop, exception_oop);
       __ jcc(Assembler::notEqual, L);
       __ stop("StubRoutines::forward exception: no pending exception (2)");
       __ bind(L);
     }
 #endif
 
+    // Verify that there is really a valid exception in RAX.
+    __ verify_oop(exception_oop);
+
+    // Restore SP from BP if the exception PC is a MethodHandle call site.
+    __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0);
+    __ cmovptr(Assembler::notEqual, rsp, rbp);
+
     // continue at exception handler (return address removed)
-    // rax,: exception
-    // rbx,: exception handler
+    // rax: exception
+    // rbx: exception handler
     // rdx: throwing pc
-    __ verify_oop(rax);
-    __ jmp(rbx);
+    __ jmp(handler_addr);
 
     return start;
   }
@@ -2263,16 +2276,6 @@
     // arraycopy stubs used by compilers
     generate_arraycopy_stubs();
 
-    // generic method handle stubs
-    if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
-      for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
-           ek < MethodHandles::_EK_LIMIT;
-           ek = MethodHandles::EntryKind(1 + (int)ek)) {
-        StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
-        MethodHandles::generate_method_handle_stub(_masm, ek);
-      }
-    }
-
     generate_math_stubs();
   }
 
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -466,7 +466,7 @@
     BLOCK_COMMENT("call exception_handler_for_return_address");
     __ call_VM_leaf(CAST_FROM_FN_PTR(address,
                          SharedRuntime::exception_handler_for_return_address),
-                    c_rarg0);
+                    r15_thread, c_rarg0);
     __ mov(rbx, rax);
 
     // setup rax & rdx, remove return address & clear pending exception
@@ -3009,16 +3009,6 @@
     // arraycopy stubs used by compilers
     generate_arraycopy_stubs();
 
-    // generic method handle stubs
-    if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
-      for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
-           ek < MethodHandles::_EK_LIMIT;
-           ek = MethodHandles::EntryKind(1 + (int)ek)) {
-        StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
-        MethodHandles::generate_method_handle_stub(_masm, ek);
-      }
-    }
-
     generate_math_stubs();
   }
 
--- a/src/cpu/x86/vm/stubRoutines_x86_32.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/stubRoutines_x86_32.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -31,6 +31,11 @@
   code_size2 = 22000            // simply increase if too small (assembler will crash if too small)
 };
 
+// MethodHandles adapters
+enum method_handles_platform_dependent_constants {
+  method_handles_adapters_code_size = 5000
+};
+
 class x86 {
  friend class StubGenerator;
  friend class VMStructs;
--- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc.  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,12 +28,14 @@
 
 static bool    returns_to_call_stub(address return_pc)   { return return_pc == _call_stub_return_address; }
 
-enum platform_dependent_constants
-{
-  code_size1 =  19000, // simply increase if too small (assembler will
-                      // crash if too small)
-  code_size2 = 22000  // simply increase if too small (assembler will
-                      // crash if too small)
+enum platform_dependent_constants {
+  code_size1 = 19000,          // simply increase if too small (assembler will crash if too small)
+  code_size2 = 22000           // simply increase if too small (assembler will crash if too small)
+};
+
+// MethodHandles adapters
+enum method_handles_platform_dependent_constants {
+  method_handles_adapters_code_size = 13000
 };
 
 class x86 {
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1550,6 +1550,7 @@
 void TemplateInterpreterGenerator::generate_throw_exception() {
   // Entry point in previous activation (i.e., if the caller was interpreted)
   Interpreter::_rethrow_exception_entry = __ pc();
+  const Register thread = rcx;
 
   // Restore sp to interpreter_frame_last_sp even though we are going
   // to empty the expression stack for the exception processing.
@@ -1598,10 +1599,10 @@
   // Set the popframe_processing bit in pending_popframe_condition indicating that we are
   // currently handling popframe, so that call_VMs that may happen later do not trigger new
   // popframe handling cycles.
-  __ get_thread(rcx);
-  __ movl(rdx, Address(rcx, JavaThread::popframe_condition_offset()));
+  __ get_thread(thread);
+  __ movl(rdx, Address(thread, JavaThread::popframe_condition_offset()));
   __ orl(rdx, JavaThread::popframe_processing_bit);
-  __ movl(Address(rcx, JavaThread::popframe_condition_offset()), rdx);
+  __ movl(Address(thread, JavaThread::popframe_condition_offset()), rdx);
 
   {
     // Check to see whether we are returning to a deoptimized frame.
@@ -1629,8 +1630,8 @@
     __ subptr(rdi, rax);
     __ addptr(rdi, wordSize);
     // Save these arguments
-    __ get_thread(rcx);
-    __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), rcx, rax, rdi);
+    __ get_thread(thread);
+    __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), thread, rax, rdi);
 
     __ remove_activation(vtos, rdx,
                          /* throw_monitor_exception */ false,
@@ -1638,8 +1639,8 @@
                          /* notify_jvmdi */ false);
 
     // Inform deoptimization that it is responsible for restoring these arguments
-    __ get_thread(rcx);
-    __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);
+    __ get_thread(thread);
+    __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_force_deopt_reexecution_bit);
 
     // Continue in deoptimization handler
     __ jmp(rdx);
@@ -1665,12 +1666,12 @@
   // expression stack if necessary.
   __ mov(rax, rsp);
   __ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
-  __ get_thread(rcx);
+  __ get_thread(thread);
   // PC must point into interpreter here
-  __ set_last_Java_frame(rcx, noreg, rbp, __ pc());
-  __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), rcx, rax, rbx);
-  __ get_thread(rcx);
-  __ reset_last_Java_frame(rcx, true, true);
+  __ set_last_Java_frame(thread, noreg, rbp, __ pc());
+  __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), thread, rax, rbx);
+  __ get_thread(thread);
+  __ reset_last_Java_frame(thread, true, true);
   // Restore the last_sp and null it out
   __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
@@ -1684,8 +1685,8 @@
   }
 
   // Clear the popframe condition flag
-  __ get_thread(rcx);
-  __ movl(Address(rcx, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
+  __ get_thread(thread);
+  __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
 
   __ dispatch_next(vtos);
   // end of PopFrame support
@@ -1694,27 +1695,27 @@
 
   // preserve exception over this code sequence
   __ pop_ptr(rax);
-  __ get_thread(rcx);
-  __ movptr(Address(rcx, JavaThread::vm_result_offset()), rax);
+  __ get_thread(thread);
+  __ movptr(Address(thread, JavaThread::vm_result_offset()), rax);
   // remove the activation (without doing throws on illegalMonitorExceptions)
   __ remove_activation(vtos, rdx, false, true, false);
   // restore exception
-  __ get_thread(rcx);
-  __ movptr(rax, Address(rcx, JavaThread::vm_result_offset()));
-  __ movptr(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD);
+  __ get_thread(thread);
+  __ movptr(rax, Address(thread, JavaThread::vm_result_offset()));
+  __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
   __ verify_oop(rax);
 
   // Inbetween activations - previous activation type unknown yet
   // compute continuation point - the continuation point expects
   // the following registers set up:
   //
-  // rax,: exception
+  // rax: exception
   // rdx: return address/pc that threw exception
   // rsp: expression stack of caller
-  // rbp,: rbp, of caller
+  // rbp: rbp, of caller
   __ push(rax);                                  // save exception
   __ push(rdx);                                  // save return address
-  __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rdx);
+  __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, rdx);
   __ mov(rbx, rax);                              // save exception handler
   __ pop(rdx);                                   // restore return address
   __ pop(rax);                                   // restore exception
@@ -1728,6 +1729,7 @@
 //
 address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) {
   address entry = __ pc();
+  const Register thread = rcx;
 
   __ restore_bcp();
   __ restore_locals();
@@ -1735,8 +1737,8 @@
   __ empty_FPU_stack();
   __ load_earlyret_value(state);
 
-  __ get_thread(rcx);
-  __ movptr(rcx, Address(rcx, JavaThread::jvmti_thread_state_offset()));
+  __ get_thread(thread);
+  __ movptr(rcx, Address(thread, JavaThread::jvmti_thread_state_offset()));
   const Address cond_addr(rcx, JvmtiThreadState::earlyret_state_offset());
 
   // Clear the earlyret state
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1741,7 +1741,7 @@
   __ push(rdx);                                  // save return address
   __ super_call_VM_leaf(CAST_FROM_FN_PTR(address,
                           SharedRuntime::exception_handler_for_return_address),
-                        rdx);
+                        r15_thread, rdx);
   __ mov(rbx, rax);                              // save exception handler
   __ pop(rdx);                                   // restore return address
   __ pop(rax);                                   // restore exception
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -2915,12 +2915,8 @@
     __ andl(recv, 0xFF);
     // recv count is 0 based?
     Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1));
-    if (is_invokedynamic) {
-      __ lea(recv, recv_addr);
-    } else {
-      __ movptr(recv, recv_addr);
-      __ verify_oop(recv);
-    }
+    __ movptr(recv, recv_addr);
+    __ verify_oop(recv);
   }
 
   // do null check if needed
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc.  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
@@ -2860,12 +2860,8 @@
     __ andl(recv, 0xFF);
     if (TaggedStackInterpreter) __ shll(recv, 1);  // index*2
     Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
-    if (is_invokedynamic) {
-      __ lea(recv, recv_addr);
-    } else {
-      __ movptr(recv, recv_addr);
-      __ verify_oop(recv);
-    }
+    __ movptr(recv, recv_addr);
+    __ verify_oop(recv);
   }
 
   // do null check if needed
--- a/src/cpu/x86/vm/x86_32.ad	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/x86_32.ad	Mon Apr 19 20:41:10 2010 -0700
@@ -1444,8 +1444,10 @@
 // to implement the UseStrictFP mode.
 const bool Matcher::strict_fp_requires_explicit_rounding = true;
 
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = true;
+// Are floats conerted to double when stored to stack during deoptimization?
+// On x32 it is stored with convertion only when FPU is used for floats.
+bool Matcher::float_in_double() { return (UseSSE == 0); }
+
 // Do ints take an entire long register or just half?
 const bool Matcher::int_in_long = false;
 
--- a/src/cpu/x86/vm/x86_64.ad	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/cpu/x86/vm/x86_64.ad	Mon Apr 19 20:41:10 2010 -0700
@@ -2074,8 +2074,10 @@
 // implement the UseStrictFP mode.
 const bool Matcher::strict_fp_requires_explicit_rounding = true;
 
-// Do floats take an entire double register or just half?
-const bool Matcher::float_in_double = true;
+// Are floats conerted to double when stored to stack during deoptimization?
+// On x64 it is stored without convertion so we can use normal access.
+bool Matcher::float_in_double() { return false; }
+
 // Do ints take an entire long register or just half?
 const bool Matcher::int_in_long = true;
 
--- a/src/os/linux/vm/os_linux.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -22,6 +22,8 @@
  *
  */
 
+# define __STDC_FORMAT_MACROS
+
 // do not include  precompiled  header file
 # include "incls/_os_linux.cpp.incl"
 
@@ -53,6 +55,8 @@
 # include <sys/ipc.h>
 # include <sys/shm.h>
 # include <link.h>
+# include <stdint.h>
+# include <inttypes.h>
 
 #define MAX_PATH    (2 * K)
 
@@ -2492,6 +2496,91 @@
     != MAP_FAILED;
 }
 
+// Linux uses a growable mapping for the stack, and if the mapping for
+// the stack guard pages is not removed when we detach a thread the
+// stack cannot grow beyond the pages where the stack guard was
+// mapped.  If at some point later in the process the stack expands to
+// that point, the Linux kernel cannot expand the stack any further
+// because the guard pages are in the way, and a segfault occurs.
+//
+// However, it's essential not to split the stack region by unmapping
+// a region (leaving a hole) that's already part of the stack mapping,
+// so if the stack mapping has already grown beyond the guard pages at
+// the time we create them, we have to truncate the stack mapping.
+// So, we need to know the extent of the stack mapping when
+// create_stack_guard_pages() is called.
+
+// Find the bounds of the stack mapping.  Return true for success.
+//
+// We only need this for stacks that are growable: at the time of
+// writing thread stacks don't use growable mappings (i.e. those
+// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
+// only applies to the main thread.
+static bool
+get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
+{
+  FILE *f = fopen("/proc/self/maps", "r");
+  if (f == NULL)
+    return false;
+
+  while (!feof(f)) {
+    size_t dummy;
+    char *str = NULL;
+    ssize_t len = getline(&str, &dummy, f);
+    if (len == -1) {
+      fclose(f);
+      return false;
+    }
+
+    if (len > 0 && str[len-1] == '\n') {
+      str[len-1] = 0;
+      len--;
+    }
+
+    static const char *stack_str = "[stack]";
+    if (len > (ssize_t)strlen(stack_str)
+       && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
+      if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
+        uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
+        if (sp >= *bottom && sp <= *top) {
+          free(str);
+          fclose(f);
+          return true;
+        }
+      }
+    }
+    free(str);
+  }
+  fclose(f);
+  return false;
+}
+
+// If the (growable) stack mapping already extends beyond the point
+// where we're going to put our guard pages, truncate the mapping at
+// that point by munmap()ping it.  This ensures that when we later
+// munmap() the guard pages we don't leave a hole in the stack
+// mapping.
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+  uintptr_t stack_extent, stack_base;
+  if (get_stack_bounds(&stack_extent, &stack_base)) {
+    if (stack_extent < (uintptr_t)addr)
+      ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
+  }
+
+  return os::commit_memory(addr, size);
+}
+
+// If this is a growable mapping, remove the guard pages entirely by
+// munmap()ping them.  If not, just call uncommit_memory().
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+  uintptr_t stack_extent, stack_base;
+  if (get_stack_bounds(&stack_extent, &stack_base)) {
+    return ::munmap(addr, size) == 0;
+  }
+
+  return os::uncommit_memory(addr, size);
+}
+
 static address _highest_vm_reserved_address = NULL;
 
 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
--- a/src/os/solaris/dtrace/hotspot.d	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/os/solaris/dtrace/hotspot.d	Mon Apr 19 20:41:10 2010 -0700
@@ -25,9 +25,20 @@
 provider hotspot {
   probe class__loaded(char*, uintptr_t, void*, uintptr_t);
   probe class__unloaded(char*, uintptr_t, void*, uintptr_t);
+  probe class__initialization__required(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__recursive(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__concurrent(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__erroneous(char*, uintptr_t, void*, intptr_t, int);
+  probe class__initialization__super__failed(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__clinit(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__error(char*, uintptr_t, void*, intptr_t,int);
+  probe class__initialization__end(char*, uintptr_t, void*, intptr_t,int);
   probe vm__init__begin();
   probe vm__init__end();
   probe vm__shutdown();
+  probe vmops__request(char*, uintptr_t, int);
+  probe vmops__begin(char*, uintptr_t, int);
+  probe vmops__end(char*, uintptr_t, int);
   probe gc__begin(uintptr_t);
   probe gc__end();
   probe mem__pool__gc__begin(
@@ -38,6 +49,12 @@
     uintptr_t, uintptr_t, uintptr_t, uintptr_t);
   probe thread__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
   probe thread__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+  probe thread__sleep__begin(long long);
+  probe thread__sleep__end(int);
+  probe thread__yield();
+  probe thread__park__begin(uintptr_t, int, long long);
+  probe thread__park__end(uintptr_t);
+  probe thread__unpark(uintptr_t);
   probe method__compile__begin(
     char*, uintptr_t, char*, uintptr_t, char*, uintptr_t, char*, uintptr_t); 
   probe method__compile__end(
--- a/src/os/solaris/vm/attachListener_solaris.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/os/solaris/vm/attachListener_solaris.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -668,13 +668,18 @@
     }
   }
 
-  if (strcmp(name, "ExtendedDTraceProbes") != 0) {
-    out->print_cr("flag '%s' cannot be changed", name);
-    return JNI_ERR;
+  if (strcmp(name, "ExtendedDTraceProbes") == 0) {
+    DTrace::set_extended_dprobes(flag);
+    return JNI_OK;
   }
 
-  DTrace::set_extended_dprobes(flag);
-  return JNI_OK;
+  if (strcmp(name, "DTraceMonitorProbes") == 0) {
+    DTrace::set_monitor_dprobes(flag);
+    return JNI_OK;
+  }
+
+  out->print_cr("flag '%s' cannot be changed", name);
+  return JNI_ERR;
 }
 
 void AttachListener::pd_detachall() {
--- a/src/os/solaris/vm/os_solaris.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -2698,6 +2698,14 @@
   }
 }
 
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+  return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+  return os::uncommit_memory(addr, size);
+}
+
 // Change the page size in a given range.
 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
   assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
--- a/src/os/windows/vm/os_windows.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -2803,6 +2803,14 @@
   return VirtualFree(addr, 0, MEM_RELEASE) != 0;
 }
 
+bool os::create_stack_guard_pages(char* addr, size_t size) {
+  return os::commit_memory(addr, size);
+}
+
+bool os::remove_stack_guard_pages(char* addr, size_t size) {
+  return os::uncommit_memory(addr, size);
+}
+
 // Set protections specified
 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
                         bool is_committed) {
--- a/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 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
@@ -29,11 +29,10 @@
 //
 
 define_pd_global(bool,  DontYieldALot,           false);
+define_pd_global(intx,  ThreadStackSize,         1536);
 #ifdef _LP64
-define_pd_global(intx,  ThreadStackSize,         1536);
 define_pd_global(intx,  VMThreadStackSize,       1024);
 #else
-define_pd_global(intx,  ThreadStackSize,         1024);
 define_pd_global(intx,  VMThreadStackSize,       512);
 #endif // _LP64
 define_pd_global(intx,  SurvivorRatio,           8);
--- a/src/share/vm/c1/c1_Canonicalizer.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_Canonicalizer.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -222,11 +222,15 @@
     }
   } else {
     LoadField* lf = x->array()->as_LoadField();
-    if (lf != NULL && lf->field()->is_constant()) {
-      ciObject* c = lf->field()->constant_value().as_object();
-      if (c->is_array()) {
-        ciArray* array = (ciArray*) c;
-        set_constant(array->length());
+    if (lf != NULL) {
+      ciField* field = lf->field();
+      if (field->is_constant() && field->is_static()) {
+        // final static field
+        ciObject* c = field->constant_value().as_object();
+        if (c->is_array()) {
+          ciArray* array = (ciArray*) c;
+          set_constant(array->length());
+        }
       }
     }
   }
--- a/src/share/vm/c1/c1_CodeStubs.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_CodeStubs.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -415,6 +415,28 @@
 };
 
 
+//------------------------------------------------------------------------------
+// DeoptimizeStub
+//
+class DeoptimizeStub : public CodeStub {
+private:
+  CodeEmitInfo* _info;
+
+public:
+  DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {}
+
+  virtual void emit_code(LIR_Assembler* e);
+  virtual CodeEmitInfo* info() const           { return _info; }
+  virtual bool is_exception_throw_stub() const { return true; }
+  virtual void visit(LIR_OpVisitState* visitor) {
+    visitor->do_slow_case(_info);
+  }
+#ifndef PRODUCT
+  virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
+#endif // PRODUCT
+};
+
+
 class SimpleExceptionStub: public CodeStub {
  private:
   LIR_Opr          _obj;
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -1524,18 +1524,14 @@
     code = Bytecodes::_invokespecial;
   }
 
-  if (code == Bytecodes::_invokedynamic) {
-    BAILOUT("invokedynamic NYI"); // FIXME
-    return;
-  }
-
   // NEEDS_CLEANUP
   // I've added the target-is_loaded() test below but I don't really understand
   // how klass->is_loaded() can be true and yet target->is_loaded() is false.
   // this happened while running the JCK invokevirtual tests under doit.  TKR
   ciMethod* cha_monomorphic_target = NULL;
   ciMethod* exact_target = NULL;
-  if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded()) {
+  if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
+      !target->is_method_handle_invoke()) {
     Value receiver = NULL;
     ciInstanceKlass* receiver_klass = NULL;
     bool type_is_exact = false;
@@ -1681,11 +1677,20 @@
   CHECK_BAILOUT();
 
   // inlining not successful => standard invoke
-  bool is_static = code == Bytecodes::_invokestatic;
+  bool is_loaded = target->is_loaded();
+  bool has_receiver =
+    code == Bytecodes::_invokespecial   ||
+    code == Bytecodes::_invokevirtual   ||
+    code == Bytecodes::_invokeinterface;
+  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
   ValueType* result_type = as_ValueType(target->return_type());
+
+  // We require the debug info to be the "state before" because
+  // invokedynamics may deoptimize.
+  ValueStack* state_before = is_invokedynamic ? state()->copy() : NULL;
+
   Values* args = state()->pop_arguments(target->arg_size_no_receiver());
-  Value recv = is_static ? NULL : apop();
-  bool is_loaded = target->is_loaded();
+  Value recv = has_receiver ? apop() : NULL;
   int vtable_index = methodOopDesc::invalid_vtable_index;
 
 #ifdef SPARC
@@ -1723,7 +1728,7 @@
     profile_call(recv, target_klass);
   }
 
-  Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target);
+  Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
   // push result
   append_split(result);
 
@@ -2862,20 +2867,18 @@
   _initial_state = state_at_entry();
   start_block->merge(_initial_state);
 
-  BlockBegin* sync_handler = NULL;
-  if (method()->is_synchronized() || _compilation->env()->dtrace_method_probes()) {
-    // setup an exception handler to do the unlocking and/or notification
-    sync_handler = new BlockBegin(-1);
-    sync_handler->set(BlockBegin::exception_entry_flag);
-    sync_handler->set(BlockBegin::is_on_work_list_flag);
-    sync_handler->set(BlockBegin::default_exception_handler_flag);
-
-    ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
-    XHandler* h = new XHandler(desc);
-    h->set_entry_block(sync_handler);
-    scope_data()->xhandlers()->append(h);
-    scope_data()->set_has_handler();
-  }
+  // setup an exception handler to do the unlocking and/or
+  // notification and unwind the frame.
+  BlockBegin* sync_handler = new BlockBegin(-1);
+  sync_handler->set(BlockBegin::exception_entry_flag);
+  sync_handler->set(BlockBegin::is_on_work_list_flag);
+  sync_handler->set(BlockBegin::default_exception_handler_flag);
+
+  ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
+  XHandler* h = new XHandler(desc);
+  h->set_entry_block(sync_handler);
+  scope_data()->xhandlers()->append(h);
+  scope_data()->set_has_handler();
 
   // complete graph
   _vmap        = new ValueMap();
--- a/src/share/vm/c1/c1_IR.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_IR.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -259,10 +259,10 @@
 }
 
 
-void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) {
+void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool is_method_handle_invoke) {
   // record the safepoint before recording the debug info for enclosing scopes
   recorder->add_safepoint(pc_offset, _oop_map->deep_copy());
-  _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/);
+  _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, is_method_handle_invoke);
   recorder->end_safepoint(pc_offset);
 }
 
--- a/src/share/vm/c1/c1_IR.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_IR.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -242,7 +242,7 @@
   //Whether we should reexecute this bytecode for deopt
   bool should_reexecute();
 
-  void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost) {
+  void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool topmost, bool is_method_handle_invoke = false) {
     if (caller() != NULL) {
       // Order is significant:  Must record caller first.
       caller()->record_debug_info(recorder, pc_offset, false/*topmost*/);
@@ -252,7 +252,6 @@
     DebugToken* monvals = recorder->create_monitor_values(monitors());
     // reexecute allowed only for the topmost frame
     bool reexecute = topmost ? should_reexecute() : false;
-    bool is_method_handle_invoke = false;
     bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
     recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
   }
@@ -303,7 +302,7 @@
   int bci() const                                { return _bci; }
 
   void add_register_oop(LIR_Opr opr);
-  void record_debug_info(DebugInformationRecorder* recorder, int pc_offset);
+  void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool is_method_handle_invoke = false);
 
   CodeEmitInfo* next() const        { return _next; }
   void set_next(CodeEmitInfo* next) { _next = next; }
--- a/src/share/vm/c1/c1_Instruction.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_Instruction.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -334,13 +334,14 @@
 
 
 Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args,
-               int vtable_index, ciMethod* target)
+               int vtable_index, ciMethod* target, ValueStack* state_before)
   : StateSplit(result_type)
   , _code(code)
   , _recv(recv)
   , _args(args)
   , _vtable_index(vtable_index)
   , _target(target)
+  , _state_before(state_before)
 {
   set_flag(TargetIsLoadedFlag,   target->is_loaded());
   set_flag(TargetIsFinalFlag,    target_is_loaded() && target->is_final_method());
@@ -355,6 +356,9 @@
   _signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0));
   if (has_receiver()) {
     _signature->append(as_BasicType(receiver()->type()));
+  } else if (is_invokedynamic()) {
+    // Add the synthetic MethodHandle argument to the signature.
+    _signature->append(T_OBJECT);
   }
   for (int i = 0; i < number_of_arguments(); i++) {
     ValueType* t = argument_at(i)->type();
@@ -364,6 +368,13 @@
 }
 
 
+void Invoke::state_values_do(void f(Value*)) {
+  StateSplit::state_values_do(f);
+  if (state_before() != NULL) state_before()->values_do(f);
+  if (state()        != NULL) state()->values_do(f);
+}
+
+
 // Implementation of Contant
 intx Constant::hash() const {
   if (_state == NULL) {
--- a/src/share/vm/c1/c1_Instruction.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_Instruction.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -1134,17 +1134,18 @@
 
 LEAF(Invoke, StateSplit)
  private:
-  Bytecodes::Code           _code;
-  Value                     _recv;
-  Values*                   _args;
-  BasicTypeList*            _signature;
-  int                       _vtable_index;
-  ciMethod*                 _target;
+  Bytecodes::Code _code;
+  Value           _recv;
+  Values*         _args;
+  BasicTypeList*  _signature;
+  int             _vtable_index;
+  ciMethod*       _target;
+  ValueStack*     _state_before;  // Required for deoptimization.
 
  public:
   // creation
   Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args,
-         int vtable_index, ciMethod* target);
+         int vtable_index, ciMethod* target, ValueStack* state_before);
 
   // accessors
   Bytecodes::Code code() const                   { return _code; }
@@ -1155,6 +1156,7 @@
   int vtable_index() const                       { return _vtable_index; }
   BasicTypeList* signature() const               { return _signature; }
   ciMethod* target() const                       { return _target; }
+  ValueStack* state_before() const               { return _state_before; }
 
   // Returns false if target is not loaded
   bool target_is_final() const                   { return check_flag(TargetIsFinalFlag); }
@@ -1162,6 +1164,9 @@
   // Returns false if target is not loaded
   bool target_is_strictfp() const                { return check_flag(TargetIsStrictfpFlag); }
 
+  // JSR 292 support
+  bool is_invokedynamic() const                  { return code() == Bytecodes::_invokedynamic; }
+
   // generic
   virtual bool can_trap() const                  { return true; }
   virtual void input_values_do(void f(Value*)) {
@@ -1169,6 +1174,7 @@
     if (has_receiver()) f(&_recv);
     for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i));
   }
+  virtual void state_values_do(void f(Value*));
 };
 
 
--- a/src/share/vm/c1/c1_LIR.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_LIR.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc.  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
@@ -76,7 +76,7 @@
       return LIR_OprFact::oopConst(type->as_ObjectType()->encoding());
     }
   }
-  case addressTag: return LIR_OprFact::intConst(type->as_AddressConstant()->value());
+  case addressTag: return LIR_OprFact::addressConst(type->as_AddressConstant()->value());
   case intTag    : return LIR_OprFact::intConst(type->as_IntConstant()->value());
   case floatTag  : return LIR_OprFact::floatConst(type->as_FloatConstant()->value());
   case longTag   : return LIR_OprFact::longConst(type->as_LongConstant()->value());
@@ -89,7 +89,7 @@
 LIR_Opr LIR_OprFact::dummy_value_type(ValueType* type) {
   switch (type->tag()) {
     case objectTag: return LIR_OprFact::oopConst(NULL);
-    case addressTag:
+    case addressTag:return LIR_OprFact::addressConst(0);
     case intTag:    return LIR_OprFact::intConst(0);
     case floatTag:  return LIR_OprFact::floatConst(0.0);
     case longTag:   return LIR_OprFact::longConst(0);
@@ -689,9 +689,10 @@
     case lir_static_call:
     case lir_optvirtual_call:
     case lir_icvirtual_call:
-    case lir_virtual_call: {
-      assert(op->as_OpJavaCall() != NULL, "must be");
-      LIR_OpJavaCall* opJavaCall = (LIR_OpJavaCall*)op;
+    case lir_virtual_call:
+    case lir_dynamic_call: {
+      LIR_OpJavaCall* opJavaCall = op->as_OpJavaCall();
+      assert(opJavaCall != NULL, "must be");
 
       if (opJavaCall->_receiver->is_valid())     do_input(opJavaCall->_receiver);
 
@@ -704,6 +705,7 @@
       }
 
       if (opJavaCall->_info)                     do_info(opJavaCall->_info);
+      if (opJavaCall->is_method_handle_invoke()) do_temp(FrameMap::method_handle_invoke_SP_save_opr());
       do_call();
       if (opJavaCall->_result->is_valid())       do_output(opJavaCall->_result);
 
@@ -1410,6 +1412,7 @@
 // LIR_Address
 void LIR_Const::print_value_on(outputStream* out) const {
   switch (type()) {
+    case T_ADDRESS:out->print("address:%d",as_jint());          break;
     case T_INT:    out->print("int:%d",   as_jint());           break;
     case T_LONG:   out->print("lng:%lld", as_jlong());          break;
     case T_FLOAT:  out->print("flt:%f",   as_jfloat());         break;
@@ -1590,6 +1593,7 @@
      case lir_optvirtual_call:       s = "optvirtual";    break;
      case lir_icvirtual_call:        s = "icvirtual";     break;
      case lir_virtual_call:          s = "virtual";       break;
+     case lir_dynamic_call:          s = "dynamic";       break;
      // LIR_OpArrayCopy
      case lir_arraycopy:             s = "arraycopy";     break;
      // LIR_OpLock
--- a/src/share/vm/c1/c1_LIR.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_LIR.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -85,9 +85,10 @@
 
   void type_check(BasicType t) const   { assert(type() == t, "type check"); }
   void type_check(BasicType t1, BasicType t2) const   { assert(type() == t1 || type() == t2, "type check"); }
+  void type_check(BasicType t1, BasicType t2, BasicType t3) const   { assert(type() == t1 || type() == t2 || type() == t3, "type check"); }
 
  public:
-  LIR_Const(jint i)                              { _value.set_type(T_INT);     _value.set_jint(i); }
+  LIR_Const(jint i, bool is_address=false)       { _value.set_type(is_address?T_ADDRESS:T_INT); _value.set_jint(i); }
   LIR_Const(jlong l)                             { _value.set_type(T_LONG);    _value.set_jlong(l); }
   LIR_Const(jfloat f)                            { _value.set_type(T_FLOAT);   _value.set_jfloat(f); }
   LIR_Const(jdouble d)                           { _value.set_type(T_DOUBLE);  _value.set_jdouble(d); }
@@ -105,7 +106,7 @@
   virtual BasicType type()       const { return _value.get_type(); }
   virtual LIR_Const* as_constant()     { return this; }
 
-  jint      as_jint()    const         { type_check(T_INT   ); return _value.get_jint(); }
+  jint      as_jint()    const         { type_check(T_INT, T_ADDRESS); return _value.get_jint(); }
   jlong     as_jlong()   const         { type_check(T_LONG  ); return _value.get_jlong(); }
   jfloat    as_jfloat()  const         { type_check(T_FLOAT ); return _value.get_jfloat(); }
   jdouble   as_jdouble() const         { type_check(T_DOUBLE); return _value.get_jdouble(); }
@@ -120,7 +121,7 @@
 #endif
 
 
-  jint      as_jint_bits() const       { type_check(T_FLOAT, T_INT); return _value.get_jint(); }
+  jint      as_jint_bits() const       { type_check(T_FLOAT, T_INT, T_ADDRESS); return _value.get_jint(); }
   jint      as_jint_lo_bits() const    {
     if (type() == T_DOUBLE) {
       return low(jlong_cast(_value.get_jdouble()));
@@ -718,6 +719,7 @@
   static LIR_Opr intptrConst(void* p)            { return (LIR_Opr)(new LIR_Const(p)); }
   static LIR_Opr intptrConst(intptr_t v)         { return (LIR_Opr)(new LIR_Const((void*)v)); }
   static LIR_Opr illegal()                       { return (LIR_Opr)-1; }
+  static LIR_Opr addressConst(jint i)            { return (LIR_Opr)(new LIR_Const(i, true)); }
 
   static LIR_Opr value_type(ValueType* type);
   static LIR_Opr dummy_value_type(ValueType* type);
@@ -840,6 +842,7 @@
       , lir_optvirtual_call
       , lir_icvirtual_call
       , lir_virtual_call
+      , lir_dynamic_call
   , end_opJavaCall
   , begin_opArrayCopy
       , lir_arraycopy
@@ -1052,6 +1055,16 @@
   LIR_Opr receiver() const                       { return _receiver; }
   ciMethod* method() const                       { return _method;   }
 
+  // JSR 292 support.
+  bool is_invokedynamic() const                  { return code() == lir_dynamic_call; }
+  bool is_method_handle_invoke() const {
+    return
+      is_invokedynamic()  // An invokedynamic is always a MethodHandle call site.
+      ||
+      (method()->holder()->name() == ciSymbol::java_dyn_MethodHandle() &&
+       method()->name()           == ciSymbol::invoke_name());
+  }
+
   intptr_t vtable_offset() const {
     assert(_code == lir_virtual_call, "only have vtable for real vcall");
     return (intptr_t) addr();
@@ -1766,6 +1779,10 @@
                     intptr_t vtable_offset, LIR_OprList* arguments, CodeEmitInfo* info) {
     append(new LIR_OpJavaCall(lir_virtual_call, method, receiver, result, vtable_offset, arguments, info));
   }
+  void call_dynamic(ciMethod* method, LIR_Opr receiver, LIR_Opr result,
+                    address dest, LIR_OprList* arguments, CodeEmitInfo* info) {
+    append(new LIR_OpJavaCall(lir_dynamic_call, method, receiver, result, dest, arguments, info));
+  }
 
   void get_thread(LIR_Opr result)                { append(new LIR_Op0(lir_get_thread, result)); }
   void word_align()                              { append(new LIR_Op0(lir_word_align)); }
--- a/src/share/vm/c1/c1_LIRAssembler.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc.  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
@@ -301,9 +301,9 @@
 }
 
 
-void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo) {
+void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo, bool is_method_handle_invoke) {
   flush_debug_info(pc_offset);
-  cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset);
+  cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset, is_method_handle_invoke);
   if (cinfo->exception_handlers() != NULL) {
     compilation()->add_exception_handlers_for_pco(pc_offset, cinfo->exception_handlers());
   }
@@ -413,6 +413,12 @@
 void LIR_Assembler::emit_call(LIR_OpJavaCall* op) {
   verify_oop_map(op->info());
 
+  // JSR 292
+  // Preserve the SP over MethodHandle call sites.
+  if (op->is_method_handle_invoke()) {
+    preserve_SP(op);
+  }
+
   if (os::is_MP()) {
     // must align calls sites, otherwise they can't be updated atomically on MP hardware
     align_call(op->code());
@@ -423,19 +429,25 @@
 
   switch (op->code()) {
   case lir_static_call:
-    call(op->addr(), relocInfo::static_call_type, op->info());
+    call(op, relocInfo::static_call_type);
     break;
   case lir_optvirtual_call:
-    call(op->addr(), relocInfo::opt_virtual_call_type, op->info());
+  case lir_dynamic_call:
+    call(op, relocInfo::opt_virtual_call_type);
     break;
   case lir_icvirtual_call:
-    ic_call(op->addr(), op->info());
+    ic_call(op);
     break;
   case lir_virtual_call:
-    vtable_call(op->vtable_offset(), op->info());
+    vtable_call(op);
     break;
   default: ShouldNotReachHere();
   }
+
+  if (op->is_method_handle_invoke()) {
+    restore_SP(op);
+  }
+
 #if defined(X86) && defined(TIERED)
   // C2 leave fpu stack dirty clean it
   if (UseSSE < 2) {
--- a/src/share/vm/c1/c1_LIRAssembler.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_LIRAssembler.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -82,7 +82,7 @@
   Address as_Address_hi(LIR_Address* addr);
 
   // debug information
-  void add_call_info(int pc_offset, CodeEmitInfo* cinfo);
+  void add_call_info(int pc_offset, CodeEmitInfo* cinfo, bool is_method_handle_invoke = false);
   void add_debug_info_for_branch(CodeEmitInfo* info);
   void add_debug_info_for_div0(int pc_offset, CodeEmitInfo* cinfo);
   void add_debug_info_for_div0_here(CodeEmitInfo* info);
@@ -205,9 +205,13 @@
   void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op);
   void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result);
 
-  void ic_call(address destination, CodeEmitInfo* info);
-  void vtable_call(int vtable_offset, CodeEmitInfo* info);
-  void call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info);
+  void call(        LIR_OpJavaCall* op, relocInfo::relocType rtype);
+  void ic_call(     LIR_OpJavaCall* op);
+  void vtable_call( LIR_OpJavaCall* op);
+
+  // JSR 292
+  void preserve_SP(LIR_OpJavaCall* op);
+  void restore_SP( LIR_OpJavaCall* op);
 
   void osr_entry();
 
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -2284,7 +2284,7 @@
 
 
 void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
-  int i = x->has_receiver() ? 1 : 0;
+  int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0;
   for (; i < args->length(); i++) {
     LIRItem* param = args->at(i);
     LIR_Opr loc = arg_list->at(i);
@@ -2322,6 +2322,10 @@
     LIRItem* receiver = new LIRItem(x->receiver(), this);
     argument_items->append(receiver);
   }
+  if (x->is_invokedynamic()) {
+    // Insert a dummy for the synthetic MethodHandle argument.
+    argument_items->append(NULL);
+  }
   int idx = x->has_receiver() ? 1 : 0;
   for (int i = 0; i < x->number_of_arguments(); i++) {
     LIRItem* param = new LIRItem(x->argument_at(i), this);
@@ -2371,6 +2375,9 @@
 
   CodeEmitInfo* info = state_for(x, x->state());
 
+  // invokedynamics can deoptimize.
+  CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL;
+
   invoke_load_arguments(x, args, arg_list);
 
   if (x->has_receiver()) {
@@ -2407,6 +2414,47 @@
         __ call_virtual(x->target(), receiver, result_register, vtable_offset, arg_list, info);
       }
       break;
+    case Bytecodes::_invokedynamic: {
+      ciBytecodeStream bcs(x->scope()->method());
+      bcs.force_bci(x->bci());
+      assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream");
+      ciCPCache* cpcache = bcs.get_cpcache();
+
+      // Get CallSite offset from constant pool cache pointer.
+      int index = bcs.get_method_index();
+      size_t call_site_offset = cpcache->get_f1_offset(index);
+
+      // If this invokedynamic call site hasn't been executed yet in
+      // the interpreter, the CallSite object in the constant pool
+      // cache is still null and we need to deoptimize.
+      if (cpcache->is_f1_null_at(index)) {
+        // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
+        // clone all handlers.  This is handled transparently in other
+        // places by the CodeEmitInfo cloning logic but is handled
+        // specially here because a stub isn't being used.
+        x->set_exception_handlers(new XHandlers(x->exception_handlers()));
+
+        DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
+        __ jump(deopt_stub);
+      }
+
+      // Use the receiver register for the synthetic MethodHandle
+      // argument.
+      receiver = LIR_Assembler::receiverOpr();
+      LIR_Opr tmp = new_register(objectType);
+
+      // Load CallSite object from constant pool cache.
+      __ oop2reg(cpcache->constant_encoding(), tmp);
+      __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
+
+      // Load target MethodHandle from CallSite object.
+      __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
+
+      __ call_dynamic(x->target(), receiver, result_register,
+                      SharedRuntime::get_resolve_opt_virtual_call_stub(),
+                      arg_list, info);
+      break;
+    }
     default:
       ShouldNotReachHere();
       break;
--- a/src/share/vm/c1/c1_LinearScan.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -2479,6 +2479,15 @@
       return 2;
     }
 
+    case T_ADDRESS: {
+#ifdef _LP64
+      scope_values->append(new ConstantLongValue(c->as_jint()));
+#else
+      scope_values->append(new ConstantIntValue(c->as_jint()));
+#endif
+      return 1;
+    }
+
     default:
       ShouldNotReachHere();
       return -1;
--- a/src/share/vm/c1/c1_MacroAssembler.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/c1/c1_MacroAssembler.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc.  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
@@ -34,7 +34,7 @@
 
   void inline_cache_check(Register receiver, Register iCache);
   void build_frame(int frame_size_in_bytes);
-  void method_exit(bool restore_frame);
+  void remove_frame(int frame_size_in_bytes);
 
   void unverified_entry(Register receiver, Register ic_klass);
   void verified_entry();
--- a/src/share/vm/ci/ciCPCache.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/ci/ciCPCache.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2009-2010 Sun Microsystems, Inc.  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
@@ -41,6 +41,16 @@
 
 
 // ------------------------------------------------------------------
+// ciCPCache::is_f1_null_at
+bool ciCPCache::is_f1_null_at(int index) {
+  VM_ENTRY_MARK;
+  constantPoolCacheOop cpcache = (constantPoolCacheOop) get_oop();
+  oop f1 = cpcache->secondary_entry_at(index)->f1();
+  return (f1 == NULL);
+}
+
+
+// ------------------------------------------------------------------
 // ciCPCache::print
 //
 // Print debugging information about the cache.
--- a/src/share/vm/ci/ciCPCache.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/ci/ciCPCache.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2009-2010 Sun Microsystems, Inc.  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
@@ -39,5 +39,7 @@
   // requested entry.
   size_t get_f1_offset(int index);
 
+  bool is_f1_null_at(int index);
+
   void print();
 };
--- a/src/share/vm/ci/ciEnv.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/ci/ciEnv.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -385,11 +385,6 @@
                                                      KILL_COMPILE_ON_FATAL_(fail_type));
   }
 
-  if (found_klass != NULL) {
-    // Found it.  Build a CI handle.
-    return get_object(found_klass)->as_klass();
-  }
-
   // If we fail to find an array klass, look again for its element type.
   // The element type may be available either locally or via constraints.
   // In either case, if we can find the element type in the system dictionary,
@@ -414,6 +409,11 @@
     }
   }
 
+  if (found_klass != NULL) {
+    // Found it.  Build a CI handle.
+    return get_object(found_klass)->as_klass();
+  }
+
   if (require_local)  return NULL;
   // Not yet loaded into the VM, or not governed by loader constraints.
   // Make a CI representative for it.
--- a/src/share/vm/classfile/loaderConstraints.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/classfile/loaderConstraints.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -334,33 +334,6 @@
   return NULL;
 }
 
-
-klassOop LoaderConstraintTable::find_constrained_elem_klass(symbolHandle name,
-                                                            symbolHandle elem_name,
-                                                            Handle loader,
-                                                            TRAPS) {
-  LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
-  if (p != NULL) {
-    assert(p->klass() == NULL, "Expecting null array klass");
-
-    // The array name has a constraint, but it will not have a class. Check
-    // each loader for an associated elem
-    for (int i = 0; i < p->num_loaders(); i++) {
-      Handle no_protection_domain;
-
-      klassOop k = SystemDictionary::find(elem_name, p->loader(i), no_protection_domain, THREAD);
-      if (k != NULL) {
-        // Return the first elem klass found.
-        return k;
-      }
-    }
-  }
-
-  // No constraints, or else no klass loaded yet.
-  return NULL;
-}
-
-
 void LoaderConstraintTable::ensure_loader_constraint_capacity(
                                                      LoaderConstraintEntry *p,
                                                     int nfree) {
--- a/src/share/vm/classfile/loaderConstraints.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/classfile/loaderConstraints.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -66,9 +66,6 @@
   //                                           bool is_method, TRAPS)
 
   klassOop find_constrained_klass(symbolHandle name, Handle loader);
-  klassOop find_constrained_elem_klass(symbolHandle name, symbolHandle elem_name,
-                                       Handle loader, TRAPS);
-
 
   // Class loader constraints
 
--- a/src/share/vm/classfile/systemDictionary.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/classfile/systemDictionary.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -2178,9 +2178,8 @@
   // a loader constraint that would require this loader to return the
   // klass that is already loaded.
   if (FieldType::is_array(class_name())) {
-    // Array classes are hard because their klassOops are not kept in the
-    // constraint table. The array klass may be constrained, but the elem class
-    // may not be.
+    // For array classes, their klassOops are not kept in the
+    // constraint table. The element klassOops are.
     jint dimension;
     symbolOop object_key;
     BasicType t = FieldType::get_array_info(class_name(), &dimension,
@@ -2190,8 +2189,9 @@
     } else {
       symbolHandle elem_name(THREAD, object_key);
       MutexLocker mu(SystemDictionary_lock, THREAD);
-      klass = constraints()->find_constrained_elem_klass(class_name, elem_name, class_loader, THREAD);
+      klass = constraints()->find_constrained_klass(elem_name, class_loader);
     }
+    // If element class already loaded, allocate array klass
     if (klass != NULL) {
       klass = Klass::cast(klass)->array_klass_or_null(dimension);
     }
@@ -2209,22 +2209,38 @@
                                              Handle class_loader1,
                                              Handle class_loader2,
                                              Thread* THREAD) {
-  unsigned int d_hash1 = dictionary()->compute_hash(class_name, class_loader1);
+  symbolHandle constraint_name;
+  if (!FieldType::is_array(class_name())) {
+    constraint_name = class_name;
+  } else {
+    // For array classes, their klassOops are not kept in the
+    // constraint table. The element classes are.
+    jint dimension;
+    symbolOop object_key;
+    BasicType t = FieldType::get_array_info(class_name(), &dimension,
+                                            &object_key, CHECK_(false));
+    // primitive types always pass
+    if (t != T_OBJECT) {
+      return true;
+    } else {
+      constraint_name = symbolHandle(THREAD, object_key);
+    }
+  }
+  unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1);
   int d_index1 = dictionary()->hash_to_index(d_hash1);
 
-  unsigned int d_hash2 = dictionary()->compute_hash(class_name, class_loader2);
+  unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, class_loader2);
   int d_index2 = dictionary()->hash_to_index(d_hash2);
+  {
+  MutexLocker mu_s(SystemDictionary_lock, THREAD);
 
-  {
-    MutexLocker mu_s(SystemDictionary_lock, THREAD);
+  // Better never do a GC while we're holding these oops
+  No_Safepoint_Verifier nosafepoint;
 
-    // Better never do a GC while we're holding these oops
-    No_Safepoint_Verifier nosafepoint;
-
-    klassOop klass1 = find_class(d_index1, d_hash1, class_name, class_loader1);
-    klassOop klass2 = find_class(d_index2, d_hash2, class_name, class_loader2);
-    return constraints()->add_entry(class_name, klass1, class_loader1,
-                                    klass2, class_loader2);
+  klassOop klass1 = find_class(d_index1, d_hash1, constraint_name, class_loader1);
+  klassOop klass2 = find_class(d_index2, d_hash2, constraint_name, class_loader2);
+  return constraints()->add_entry(constraint_name, klass1, class_loader1,
+                                  klass2, class_loader2);
   }
 }
 
@@ -2301,6 +2317,7 @@
 // Returns the name of the type that failed a loader constraint check, or
 // NULL if no constraint failed. The returned C string needs cleaning up
 // with a ResourceMark in the caller.  No exception except OOME is thrown.
+// Arrays are not added to the loader constraint table, their elements are.
 char* SystemDictionary::check_signature_loaders(symbolHandle signature,
                                                Handle loader1, Handle loader2,
                                                bool is_method, TRAPS)  {
--- a/src/share/vm/code/codeBlob.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/code/codeBlob.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2010 Sun Microsystems, Inc.  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
@@ -249,7 +249,6 @@
   size += round_to(buffer_size, oopSize);
   assert(name != NULL, "must provide a name");
   {
-
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     blob = new (size) BufferBlob(name, size);
   }
@@ -271,7 +270,6 @@
   unsigned int size = allocation_size(cb, sizeof(BufferBlob));
   assert(name != NULL, "must provide a name");
   {
-
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     blob = new (size) BufferBlob(name, size, cb);
   }
@@ -298,10 +296,48 @@
   MemoryService::track_code_cache_memory_usage();
 }
 
-bool BufferBlob::is_adapter_blob() const {
-  return (strcmp(AdapterHandlerEntry::name, name()) == 0);
+
+//----------------------------------------------------------------------------------------------------
+// Implementation of AdapterBlob
+
+AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
+  ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
+
+  AdapterBlob* blob = NULL;
+  unsigned int size = allocation_size(cb, sizeof(AdapterBlob));
+  {
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    blob = new (size) AdapterBlob(size, cb);
+  }
+  // Track memory usage statistic after releasing CodeCache_lock
+  MemoryService::track_code_cache_memory_usage();
+
+  return blob;
 }
 
+
+//----------------------------------------------------------------------------------------------------
+// Implementation of MethodHandlesAdapterBlob
+
+MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {
+  ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
+
+  MethodHandlesAdapterBlob* blob = NULL;
+  unsigned int size = sizeof(MethodHandlesAdapterBlob);
+  // align the size to CodeEntryAlignment
+  size = align_code_offset(size);
+  size += round_to(buffer_size, oopSize);
+  {
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    blob = new (size) MethodHandlesAdapterBlob(size);
+  }
+  // Track memory usage statistic after releasing CodeCache_lock
+  MemoryService::track_code_cache_memory_usage();
+
+  return blob;
+}
+
+
 //----------------------------------------------------------------------------------------------------
 // Implementation of RuntimeStub
 
--- a/src/share/vm/code/codeBlob.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/code/codeBlob.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2010 Sun Microsystems, Inc.  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
@@ -90,14 +90,15 @@
   void flush();
 
   // Typing
-  virtual bool is_buffer_blob() const            { return false; }
-  virtual bool is_nmethod() const                { return false; }
-  virtual bool is_runtime_stub() const           { return false; }
-  virtual bool is_deoptimization_stub() const    { return false; }
-  virtual bool is_uncommon_trap_stub() const     { return false; }
-  virtual bool is_exception_stub() const         { return false; }
-  virtual bool is_safepoint_stub() const         { return false; }
-  virtual bool is_adapter_blob() const           { return false; }
+  virtual bool is_buffer_blob() const                 { return false; }
+  virtual bool is_nmethod() const                     { return false; }
+  virtual bool is_runtime_stub() const                { return false; }
+  virtual bool is_deoptimization_stub() const         { return false; }
+  virtual bool is_uncommon_trap_stub() const          { return false; }
+  virtual bool is_exception_stub() const              { return false; }
+  virtual bool is_safepoint_stub() const              { return false; }
+  virtual bool is_adapter_blob() const                { return false; }
+  virtual bool is_method_handles_adapter_blob() const { return false; }
 
   virtual bool is_compiled_by_c2() const         { return false; }
   virtual bool is_compiled_by_c1() const         { return false; }
@@ -221,6 +222,9 @@
 
 class BufferBlob: public CodeBlob {
   friend class VMStructs;
+  friend class AdapterBlob;
+  friend class MethodHandlesAdapterBlob;
+
  private:
   // Creation support
   BufferBlob(const char* name, int size);
@@ -236,8 +240,7 @@
   static void free(BufferBlob* buf);
 
   // Typing
-  bool is_buffer_blob() const                    { return true; }
-  bool is_adapter_blob() const;
+  virtual bool is_buffer_blob() const            { return true; }
 
   // GC/Verification support
   void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f)  { /* nothing to do */ }
@@ -255,6 +258,40 @@
 
 
 //----------------------------------------------------------------------------------------------------
+// AdapterBlob: used to hold C2I/I2C adapters
+
+class AdapterBlob: public BufferBlob {
+private:
+  AdapterBlob(int size)                 : BufferBlob("I2C/C2I adapters", size) {}
+  AdapterBlob(int size, CodeBuffer* cb) : BufferBlob("I2C/C2I adapters", size, cb) {}
+
+public:
+  // Creation
+  static AdapterBlob* create(CodeBuffer* cb);
+
+  // Typing
+  virtual bool is_adapter_blob() const { return true; }
+};
+
+
+//----------------------------------------------------------------------------------------------------
+// MethodHandlesAdapterBlob: used to hold MethodHandles adapters
+
+class MethodHandlesAdapterBlob: public BufferBlob {
+private:
+  MethodHandlesAdapterBlob(int size)                 : BufferBlob("MethodHandles adapters", size) {}
+  MethodHandlesAdapterBlob(int size, CodeBuffer* cb) : BufferBlob("MethodHandles adapters", size, cb) {}
+
+public:
+  // Creation
+  static MethodHandlesAdapterBlob* create(int buffer_size);
+
+  // Typing
+  virtual bool is_method_handles_adapter_blob() const { return true; }
+};
+
+
+//----------------------------------------------------------------------------------------------------
 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
 
 class RuntimeStub: public CodeBlob {
--- a/src/share/vm/compiler/compileBroker.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/compiler/compileBroker.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -988,10 +988,12 @@
     }
     if (method->is_not_compilable(comp_level)) return NULL;
 
-    nmethod* saved = CodeCache::find_and_remove_saved_code(method());
-    if (saved != NULL) {
-      method->set_code(method, saved);
-      return saved;
+    if (UseCodeCacheFlushing) {
+      nmethod* saved = CodeCache::find_and_remove_saved_code(method());
+      if (saved != NULL) {
+        method->set_code(method, saved);
+        return saved;
+      }
     }
 
   } else {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -46,9 +46,9 @@
 
   _processor_count = os::active_processor_count();
 
-  if (CMSConcurrentMTEnabled && (ParallelCMSThreads > 1)) {
+  if (CMSConcurrentMTEnabled && (ConcGCThreads > 1)) {
     assert(_processor_count > 0, "Processor count is suspect");
-    _concurrent_processor_count = MIN2((uint) ParallelCMSThreads,
+    _concurrent_processor_count = MIN2((uint) ConcGCThreads,
                                        (uint) _processor_count);
   } else {
     _concurrent_processor_count = 1;
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -606,7 +606,7 @@
     assert(_modUnionTable.covers(_span), "_modUnionTable inconsistency?");
   }
 
-  if (!_markStack.allocate(CMSMarkStackSize)) {
+  if (!_markStack.allocate(MarkStackSize)) {
     warning("Failed to allocate CMS Marking Stack");
     return;
   }
@@ -617,13 +617,13 @@
 
   // Support for multi-threaded concurrent phases
   if (ParallelGCThreads > 0 && CMSConcurrentMTEnabled) {
-    if (FLAG_IS_DEFAULT(ParallelCMSThreads)) {
+    if (FLAG_IS_DEFAULT(ConcGCThreads)) {
       // just for now
-      FLAG_SET_DEFAULT(ParallelCMSThreads, (ParallelGCThreads + 3)/4);
-    }
-    if (ParallelCMSThreads > 1) {
+      FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
+    }
+    if (ConcGCThreads > 1) {
       _conc_workers = new YieldingFlexibleWorkGang("Parallel CMS Threads",
-                                 ParallelCMSThreads, true);
+                                 ConcGCThreads, true);
       if (_conc_workers == NULL) {
         warning("GC/CMS: _conc_workers allocation failure: "
               "forcing -CMSConcurrentMTEnabled");
@@ -634,13 +634,13 @@
     }
   }
   if (!CMSConcurrentMTEnabled) {
-    ParallelCMSThreads = 0;
+    ConcGCThreads = 0;
   } else {
     // Turn off CMSCleanOnEnter optimization temporarily for
     // the MT case where it's not fixed yet; see 6178663.
     CMSCleanOnEnter = false;
   }
-  assert((_conc_workers != NULL) == (ParallelCMSThreads > 1),
+  assert((_conc_workers != NULL) == (ConcGCThreads > 1),
          "Inconsistency");
 
   // Parallel task queues; these are shared for the
@@ -648,7 +648,7 @@
   // are not shared with parallel scavenge (ParNew).
   {
     uint i;
-    uint num_queues = (uint) MAX2(ParallelGCThreads, ParallelCMSThreads);
+    uint num_queues = (uint) MAX2(ParallelGCThreads, ConcGCThreads);
 
     if ((CMSParallelRemarkEnabled || CMSConcurrentMTEnabled
          || ParallelRefProcEnabled)
@@ -723,8 +723,9 @@
 
   // Support for parallelizing survivor space rescan
   if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
-    size_t max_plab_samples = cp->max_gen0_size()/
-                                ((SurvivorRatio+2)*MinTLABSize);
+    const size_t max_plab_samples =
+      ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
+
     _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
     _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
     _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
@@ -3657,7 +3658,7 @@
   assert(_revisitStack.isEmpty(), "tabula rasa");
   DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
   bool result = false;
-  if (CMSConcurrentMTEnabled && ParallelCMSThreads > 0) {
+  if (CMSConcurrentMTEnabled && ConcGCThreads > 0) {
     result = do_marking_mt(asynch);
   } else {
     result = do_marking_st(asynch);
@@ -4174,10 +4175,10 @@
 }
 
 bool CMSCollector::do_marking_mt(bool asynch) {
-  assert(ParallelCMSThreads > 0 && conc_workers() != NULL, "precondition");
+  assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
   // In the future this would be determined ergonomically, based
   // on #cpu's, # active mutator threads (and load), and mutation rate.
-  int num_workers = ParallelCMSThreads;
+  int num_workers = ConcGCThreads;
 
   CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
   CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
@@ -6429,8 +6430,8 @@
 // For now we take the expedient path of just disabling the
 // messages for the problematic case.)
 void CMSMarkStack::expand() {
-  assert(_capacity <= CMSMarkStackSizeMax, "stack bigger than permitted");
-  if (_capacity == CMSMarkStackSizeMax) {
+  assert(_capacity <= MarkStackSizeMax, "stack bigger than permitted");
+  if (_capacity == MarkStackSizeMax) {
     if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
       // We print a warning message only once per CMS cycle.
       gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
@@ -6438,7 +6439,7 @@
     return;
   }
   // Double capacity if possible
-  size_t new_capacity = MIN2(_capacity*2, CMSMarkStackSizeMax);
+  size_t new_capacity = MIN2(_capacity*2, MarkStackSizeMax);
   // Do not give up existing stack until we have managed to
   // get the double capacity that we desired.
   ReservedSpace rs(ReservedSpace::allocation_align_size_up(
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -44,20 +44,20 @@
 {
 
   // Ergomonically select initial concurrent refinement parameters
-  if (FLAG_IS_DEFAULT(G1ConcRefineGreenZone)) {
-    FLAG_SET_DEFAULT(G1ConcRefineGreenZone, MAX2<int>(ParallelGCThreads, 1));
+  if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
+    FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, MAX2<int>(ParallelGCThreads, 1));
   }
-  set_green_zone(G1ConcRefineGreenZone);
+  set_green_zone(G1ConcRefinementGreenZone);
 
-  if (FLAG_IS_DEFAULT(G1ConcRefineYellowZone)) {
-    FLAG_SET_DEFAULT(G1ConcRefineYellowZone, green_zone() * 3);
+  if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
+    FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3);
   }
-  set_yellow_zone(MAX2<int>(G1ConcRefineYellowZone, green_zone()));
+  set_yellow_zone(MAX2<int>(G1ConcRefinementYellowZone, green_zone()));
 
-  if (FLAG_IS_DEFAULT(G1ConcRefineRedZone)) {
-    FLAG_SET_DEFAULT(G1ConcRefineRedZone, yellow_zone() * 2);
+  if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
+    FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
   }
-  set_red_zone(MAX2<int>(G1ConcRefineRedZone, yellow_zone()));
+  set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone()));
   _n_worker_threads = thread_num();
   // We need one extra thread to do the young gen rset size sampling.
   _n_threads = _n_worker_threads + 1;
@@ -76,15 +76,15 @@
 }
 
 void ConcurrentG1Refine::reset_threshold_step() {
-  if (FLAG_IS_DEFAULT(G1ConcRefineThresholdStep)) {
+  if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) {
     _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
   } else {
-    _thread_threshold_step = G1ConcRefineThresholdStep;
+    _thread_threshold_step = G1ConcRefinementThresholdStep;
   }
 }
 
 int ConcurrentG1Refine::thread_num() {
-  return MAX2<int>((G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads, 1);
+  return MAX2<int>((G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads : ParallelGCThreads, 1);
 }
 
 void ConcurrentG1Refine::init() {
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -39,7 +39,8 @@
   * running. If the length becomes red (max queue length) the mutators start
   * processing the buffers.
   *
-  * There are some interesting cases (with G1AdaptiveConcRefine turned off):
+  * There are some interesting cases (when G1UseAdaptiveConcRefinement
+  * is turned off):
   * 1) green = yellow = red = 0. In this case the mutator will process all
   *    buffers. Except for those that are created by the deferred updates
   *    machinery during a collection.
--- a/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -107,7 +107,7 @@
     if (_should_terminate) {
       break;
     }
-    _monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefineServiceInterval);
+    _monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefinementServiceIntervalMillis);
   }
 }
 
@@ -127,7 +127,7 @@
 void ConcurrentG1RefineThread::activate() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   if (_worker_id > 0) {
-    if (G1TraceConcurrentRefinement) {
+    if (G1TraceConcRefinement) {
       DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
       gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
                              _worker_id, _threshold, (int)dcqs.completed_buffers_num());
@@ -143,7 +143,7 @@
 void ConcurrentG1RefineThread::deactivate() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   if (_worker_id > 0) {
-    if (G1TraceConcurrentRefinement) {
+    if (G1TraceConcRefinement) {
       DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
       gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
                              _worker_id, _deactivation_threshold, (int)dcqs.completed_buffers_num());
@@ -218,9 +218,13 @@
 
 
 void ConcurrentG1RefineThread::yield() {
-  if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield");
+  if (G1TraceConcRefinement) {
+    gclog_or_tty->print_cr("G1-Refine-yield");
+  }
   _sts.yield("G1 refine");
-  if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield-end");
+  if (G1TraceConcRefinement) {
+    gclog_or_tty->print_cr("G1-Refine-yield-end");
+  }
 }
 
 void ConcurrentG1RefineThread::stop() {
@@ -241,7 +245,9 @@
       Terminator_lock->wait();
     }
   }
-  if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-stop");
+  if (G1TraceConcRefinement) {
+    gclog_or_tty->print_cr("G1-Refine-stop");
+  }
 }
 
 void ConcurrentG1RefineThread::print() const {
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -447,7 +447,7 @@
     gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", "
                            "heap end = "PTR_FORMAT, _heap_start, _heap_end);
 
-  _markStack.allocate(G1MarkStackSize);
+  _markStack.allocate(MarkStackSize);
   _regionStack.allocate(G1MarkRegionStackSize);
 
   // Create & start a ConcurrentMark thread.
@@ -461,7 +461,7 @@
   assert(_markBitMap2.covers(rs), "_markBitMap2 inconsistency");
 
   SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
-  satb_qs.set_buffer_size(G1SATBLogBufferSize);
+  satb_qs.set_buffer_size(G1SATBBufferSize);
 
   int size = (int) MAX2(ParallelGCThreads, (size_t)1);
   _par_cleanup_thread_state = NEW_C_HEAP_ARRAY(ParCleanupThreadState*, size);
@@ -483,8 +483,8 @@
     _accum_task_vtime[i] = 0.0;
   }
 
-  if (ParallelMarkingThreads > ParallelGCThreads) {
-    vm_exit_during_initialization("Can't have more ParallelMarkingThreads "
+  if (ConcGCThreads > ParallelGCThreads) {
+    vm_exit_during_initialization("Can't have more ConcGCThreads "
                                   "than ParallelGCThreads.");
   }
   if (ParallelGCThreads == 0) {
@@ -494,11 +494,11 @@
     _sleep_factor             = 0.0;
     _marking_task_overhead    = 1.0;
   } else {
-    if (ParallelMarkingThreads > 0) {
-      // notice that ParallelMarkingThreads overwrites G1MarkingOverheadPercent
+    if (ConcGCThreads > 0) {
+      // notice that ConcGCThreads overwrites G1MarkingOverheadPercent
       // if both are set
 
-      _parallel_marking_threads = ParallelMarkingThreads;
+      _parallel_marking_threads = ConcGCThreads;
       _sleep_factor             = 0.0;
       _marking_task_overhead    = 1.0;
     } else if (G1MarkingOverheadPercent > 0) {
@@ -760,7 +760,10 @@
   rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
 
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
-  satb_mq_set.set_active_all_threads(true);
+  // This is the start of  the marking cycle, we're expected all
+  // threads to have SATB queues with active set to false.
+  satb_mq_set.set_active_all_threads(true, /* new active value */
+                                     false /* expected_active */);
 
   // update_g1_committed() will be called at the end of an evac pause
   // when marking is on. So, it's also called at the end of the
@@ -1079,7 +1082,11 @@
       gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
   } else {
     // We're done with marking.
-    JavaThread::satb_mark_queue_set().set_active_all_threads(false);
+    // This is the end of  the marking cycle, we're expected all
+    // threads to have SATB queues with active set to true.
+    JavaThread::satb_mark_queue_set().set_active_all_threads(
+                                                  false, /* new active value */
+                                                  true /* expected_active */);
 
     if (VerifyDuringGC) {
       HandleMark hm;  // handle scope
@@ -2586,7 +2593,11 @@
 
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
   satb_mq_set.abandon_partial_marking();
-  satb_mq_set.set_active_all_threads(false);
+  // This can be called either during or outside marking, we'll read
+  // the expected_active value from the SATB queue set.
+  satb_mq_set.set_active_all_threads(
+                                 false, /* new active value */
+                                 satb_mq_set.is_active() /* expected_active */);
 }
 
 static void print_ms_time_info(const char* prefix, const char* name,
@@ -3704,7 +3715,14 @@
         // enough to point to the next possible object header (the
         // bitmap knows by how much we need to move it as it knows its
         // granularity).
-        move_finger_to(_nextMarkBitMap->nextWord(_finger));
+        assert(_finger < _region_limit, "invariant");
+        HeapWord* new_finger = _nextMarkBitMap->nextWord(_finger);
+        // Check if bitmap iteration was aborted while scanning the last object
+        if (new_finger >= _region_limit) {
+            giveup_current_region();
+        } else {
+            move_finger_to(new_finger);
+        }
       }
     }
     // At this point we have either completed iterating over the
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -24,8 +24,8 @@
 
 class G1CollectedHeap;
 class CMTask;
-typedef GenericTaskQueue<oop> CMTaskQueue;
-typedef GenericTaskQueueSet<oop> CMTaskQueueSet;
+typedef GenericTaskQueue<oop>            CMTaskQueue;
+typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
 
 // A generic CM bit map.  This is essentially a wrapper around the BitMap
 // class, with one bit per (1<<_shifter) HeapWords.
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -583,7 +583,7 @@
            res->zero_fill_state() == HeapRegion::Allocated)),
          "Non-young alloc Regions must be zero filled (and non-H)");
 
-  if (G1PrintRegions) {
+  if (G1PrintHeapRegions) {
     if (res != NULL) {
       gclog_or_tty->print_cr("new alloc region %d:["PTR_FORMAT", "PTR_FORMAT"], "
                              "top "PTR_FORMAT,
@@ -2102,18 +2102,21 @@
 size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const {
   // Return the remaining space in the cur alloc region, but not less than
   // the min TLAB size.
-  // Also, no more than half the region size, since we can't allow tlabs to
-  // grow big enough to accomodate humongous objects.
-
-  // We need to story it locally, since it might change between when we
-  // test for NULL and when we use it later.
+
+  // Also, this value can be at most the humongous object threshold,
+  // since we can't allow tlabs to grow big enough to accomodate
+  // humongous objects.
+
+  // We need to store the cur alloc region locally, since it might change
+  // between when we test for NULL and when we use it later.
   ContiguousSpace* cur_alloc_space = _cur_alloc_region;
+  size_t max_tlab_size = _humongous_object_threshold_in_words * wordSize;
+
   if (cur_alloc_space == NULL) {
-    return HeapRegion::GrainBytes/2;
+    return max_tlab_size;
   } else {
-    return MAX2(MIN2(cur_alloc_space->free(),
-                     (size_t)(HeapRegion::GrainBytes/2)),
-                (size_t)MinTLABSize);
+    return MIN2(MAX2(cur_alloc_space->free(), (size_t)MinTLABSize),
+                max_tlab_size);
   }
 }
 
@@ -2477,7 +2480,7 @@
   if (G1SummarizeRSetStats) {
     g1_rem_set()->print_summary_info();
   }
-  if (G1SummarizeConcurrentMark) {
+  if (G1SummarizeConcMark) {
     concurrent_mark()->print_summary_info();
   }
   if (G1SummarizeZFStats) {
@@ -3480,7 +3483,7 @@
   HeapRegion* r = heap_region_containing(old);
   if (!r->evacuation_failed()) {
     r->set_evacuation_failed(true);
-    if (G1PrintRegions) {
+    if (G1PrintHeapRegions) {
       gclog_or_tty->print("evacuation failed in heap region "PTR_FORMAT" "
                           "["PTR_FORMAT","PTR_FORMAT")\n",
                           r, r->bottom(), r->end());
@@ -4002,9 +4005,7 @@
       _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms);
       _g1h->g1_policy()->record_termination_time(i, term_ms);
     }
-    if (G1UseSurvivorSpaces) {
-      _g1h->g1_policy()->record_thread_age_table(pss.age_table());
-    }
+    _g1h->g1_policy()->record_thread_age_table(pss.age_table());
     _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
 
     // Clean up any par-expanded rem sets.
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -56,8 +56,8 @@
 #  define IF_G1_DETAILED_STATS(code)
 #endif
 
-typedef GenericTaskQueue<StarTask>    RefToScanQueue;
-typedef GenericTaskQueueSet<StarTask> RefToScanQueueSet;
+typedef GenericTaskQueue<StarTask>          RefToScanQueue;
+typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
 
 typedef int RegionIdx_t;   // needs to hold [ 0..max_regions() )
 typedef int CardIdx_t;     // needs to hold [ 0..CardsPerRegion )
@@ -1055,7 +1055,12 @@
 
   // Returns "true" iff the given word_size is "very large".
   static bool isHumongous(size_t word_size) {
-    return word_size >= _humongous_object_threshold_in_words;
+    // Note this has to be strictly greater-than as the TLABs
+    // are capped at the humongous thresold and we want to
+    // ensure that we don't try to allocate a TLAB as
+    // humongous and that we don't allocate a humongous
+    // object in a TLAB.
+    return word_size > _humongous_object_threshold_in_words;
   }
 
   // Update mod union table with the set of dirty cards.
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -270,14 +270,10 @@
   _concurrent_mark_cleanup_times_ms->add(0.20);
   _tenuring_threshold = MaxTenuringThreshold;
 
-  if (G1UseSurvivorSpaces) {
-    // if G1FixedSurvivorSpaceSize is 0 which means the size is not
-    // fixed, then _max_survivor_regions will be calculated at
-    // calculate_young_list_target_config during initialization
-    _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
-  } else {
-    _max_survivor_regions = 0;
-  }
+  // if G1FixedSurvivorSpaceSize is 0 which means the size is not
+  // fixed, then _max_survivor_regions will be calculated at
+  // calculate_young_list_target_config during initialization
+  _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
 
   initialize_all();
 }
@@ -296,28 +292,54 @@
   CollectorPolicy::initialize_flags();
 }
 
+// The easiest way to deal with the parsing of the NewSize /
+// MaxNewSize / etc. parameteres is to re-use the code in the
+// TwoGenerationCollectorPolicy class. This is similar to what
+// ParallelScavenge does with its GenerationSizer class (see
+// ParallelScavengeHeap::initialize()). We might change this in the
+// future, but it's a good start.
+class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
+  size_t size_to_region_num(size_t byte_size) {
+    return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
+  }
+
+public:
+  G1YoungGenSizer() {
+    initialize_flags();
+    initialize_size_info();
+  }
+
+  size_t min_young_region_num() {
+    return size_to_region_num(_min_gen0_size);
+  }
+  size_t initial_young_region_num() {
+    return size_to_region_num(_initial_gen0_size);
+  }
+  size_t max_young_region_num() {
+    return size_to_region_num(_max_gen0_size);
+  }
+};
+
 void G1CollectorPolicy::init() {
   // Set aside an initial future to_space.
   _g1 = G1CollectedHeap::heap();
-  size_t regions = Universe::heap()->capacity() / HeapRegion::GrainBytes;
 
   assert(Heap_lock->owned_by_self(), "Locking discipline.");
 
-  if (G1SteadyStateUsed < 50) {
-    vm_exit_during_initialization("G1SteadyStateUsed must be at least 50%.");
-  }
-
   initialize_gc_policy_counters();
 
   if (G1Gen) {
     _in_young_gc_mode = true;
 
-    if (G1YoungGenSize == 0) {
+    G1YoungGenSizer sizer;
+    size_t initial_region_num = sizer.initial_young_region_num();
+
+    if (UseAdaptiveSizePolicy) {
       set_adaptive_young_list_length(true);
       _young_list_fixed_length = 0;
     } else {
       set_adaptive_young_list_length(false);
-      _young_list_fixed_length = (G1YoungGenSize / HeapRegion::GrainBytes);
+      _young_list_fixed_length = initial_region_num;
     }
      _free_regions_at_end_of_collection = _g1->free_regions();
      _scan_only_regions_at_end_of_collection = 0;
@@ -455,7 +477,7 @@
   guarantee( adaptive_young_list_length(), "pre-condition" );
 
   double start_time_sec = os::elapsedTime();
-  size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1MinReservePercent);
+  size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1ReservePercent);
   min_reserve_perc = MIN2((size_t) 50, min_reserve_perc);
   size_t reserve_regions =
     (size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0);
@@ -1110,10 +1132,7 @@
   size_t short_lived_so_length = _young_list_so_prefix_length;
   _short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length);
   tag_scan_only(short_lived_so_length);
-
-  if (G1UseSurvivorSpaces) {
-    _survivors_age_table.clear();
-  }
+  _survivors_age_table.clear();
 
   assert( verify_young_ages(), "region age verification" );
 }
@@ -1432,7 +1451,7 @@
       record_concurrent_mark_init_end_pre(0.0);
 
     size_t min_used_targ =
-      (_g1->capacity() / 100) * (G1SteadyStateUsed - G1SteadyStateUsedDelta);
+      (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent;
 
     if (cur_used_bytes > min_used_targ) {
       if (cur_used_bytes <= _prev_collection_pause_used_at_end_bytes) {
@@ -1916,7 +1935,7 @@
   calculate_young_list_target_config();
 
   // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
-  double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSUpdatePauseFractionPercent / 100.0;
+  double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
   adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms);
 
   // </NEW PREDICTION>
@@ -1932,7 +1951,7 @@
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
 
-  if (G1AdaptiveConcRefine) {
+  if (G1UseAdaptiveConcRefinement) {
     const int k_gy = 3, k_gr = 6;
     const double inc_k = 1.1, dec_k = 0.9;
 
@@ -2607,9 +2626,6 @@
 // Calculates survivor space parameters.
 void G1CollectorPolicy::calculate_survivors_policy()
 {
-  if (!G1UseSurvivorSpaces) {
-    return;
-  }
   if (G1FixedSurvivorSpaceSize == 0) {
     _max_survivor_regions = _young_list_target_length / SurvivorRatio;
   } else {
@@ -2628,13 +2644,6 @@
 G1CollectorPolicy_BestRegionsFirst::should_do_collection_pause(size_t
                                                                word_size) {
   assert(_g1->regions_accounted_for(), "Region leakage!");
-  // Initiate a pause when we reach the steady-state "used" target.
-  size_t used_hard = (_g1->capacity() / 100) * G1SteadyStateUsed;
-  size_t used_soft =
-   MAX2((_g1->capacity() / 100) * (G1SteadyStateUsed - G1SteadyStateUsedDelta),
-        used_hard/2);
-  size_t used = _g1->used();
-
   double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
 
   size_t young_list_length = _g1->young_list_length();
@@ -2867,7 +2876,7 @@
 // estimate of the number of live bytes.
 void G1CollectorPolicy::
 add_to_collection_set(HeapRegion* hr) {
-  if (G1PrintRegions) {
+  if (G1PrintHeapRegions) {
     gclog_or_tty->print_cr("added region to cset %d:["PTR_FORMAT", "PTR_FORMAT"], "
                   "top "PTR_FORMAT", young %s",
                   hr->hrs_index(), hr->bottom(), hr->end(),
--- a/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -88,13 +88,13 @@
     //     the time slice than what's allowed)
     //   consolidate the two entries with the minimum gap between them
     //     (this might allow less GC time than what's allowed)
-    guarantee(NOT_PRODUCT(ScavengeALot ||) G1ForgetfulMMUTracker,
-              "array full, currently we can't recover unless +G1ForgetfulMMUTracker");
+    guarantee(NOT_PRODUCT(ScavengeALot ||) G1UseFixedWindowMMUTracker,
+              "array full, currently we can't recover unless +G1UseFixedWindowMMUTracker");
     // In the case where ScavengeALot is true, such overflow is not
     // uncommon; in such cases, we can, without much loss of precision
     // or performance (we are GC'ing most of the time anyway!),
     // simply overwrite the oldest entry in the tracker: this
-    // is also the behaviour when G1ForgetfulMMUTracker is enabled.
+    // is also the behaviour when G1UseFixedWindowMMUTracker is enabled.
     _head_index = trim_index(_head_index + 1);
     assert(_head_index == _tail_index, "Because we have a full circular buffer");
     _tail_index = trim_index(_tail_index + 1);
--- a/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -101,7 +101,7 @@
   // If the array is full, an easy fix is to look for the pauses with
   // the shortest gap between them and consolidate them.
   // For now, we have taken the expedient alternative of forgetting
-  // the oldest entry in the event that +G1ForgetfulMMUTracker, thus
+  // the oldest entry in the event that +G1UseFixedWindowMMUTracker, thus
   // potentially violating MMU specs for some time thereafter.
 
   G1MMUTrackerQueueElem _array[QueueLength];
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -101,6 +101,8 @@
 
   GenMarkSweep::_marking_stack =
     new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
+  GenMarkSweep::_objarray_stack =
+    new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true);
 
   int size = SystemDictionary::number_of_classes() * 2;
   GenMarkSweep::_revisit_klass_stack =
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -467,7 +467,7 @@
     // and they are causing failures. When we resolve said race
     // conditions, we'll revert back to parallel remembered set
     // updating and scanning. See CRs 6677707 and 6677708.
-    if (G1ParallelRSetUpdatingEnabled || (worker_i == 0)) {
+    if (G1UseParallelRSetUpdating || (worker_i == 0)) {
       updateRS(worker_i);
       scanNewRefsRS(oc, worker_i);
     } else {
@@ -476,7 +476,7 @@
       _g1p->record_update_rs_time(worker_i, 0.0);
       _g1p->record_scan_new_refs_time(worker_i, 0.0);
     }
-    if (G1ParallelRSetScanningEnabled || (worker_i == 0)) {
+    if (G1UseParallelRSetScanning || (worker_i == 0)) {
       scanRS(oc, worker_i);
     } else {
       _g1p->record_scan_rs_start_time(worker_i, os::elapsedTime() * 1000.0);
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -35,7 +35,7 @@
 
 void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
   assert(pre_val->is_oop_or_null(true), "Error");
-  if (!JavaThread::satb_mark_queue_set().active()) return;
+  if (!JavaThread::satb_mark_queue_set().is_active()) return;
   Thread* thr = Thread::current();
   if (thr->is_Java_thread()) {
     JavaThread* jt = (JavaThread*)thr;
@@ -51,7 +51,7 @@
 G1SATBCardTableModRefBS::write_ref_field_pre_static(T* field,
                                                     oop new_val,
                                                     JavaThread* jt) {
-  if (!JavaThread::satb_mark_queue_set().active()) return;
+  if (!JavaThread::satb_mark_queue_set().is_active()) return;
   T heap_oop = oopDesc::load_heap_oop(field);
   if (!oopDesc::is_null(heap_oop)) {
     oop pre_val = oopDesc::decode_heap_oop_not_null(heap_oop);
@@ -62,7 +62,7 @@
 
 template <class T> void
 G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) {
-  if (!JavaThread::satb_mark_queue_set().active()) return;
+  if (!JavaThread::satb_mark_queue_set().is_active()) return;
   T* elem_ptr = dst;
   for (int i = 0; i < count; i++, elem_ptr++) {
     T heap_oop = oopDesc::load_heap_oop(elem_ptr);
--- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -37,9 +37,6 @@
   develop(intx, G1MarkingOverheadPercent, 0,                                \
           "Overhead of concurrent marking")                                 \
                                                                             \
-  product(uintx, G1YoungGenSize, 0,                                         \
-          "Size of the G1 young generation, 0 is the adaptive policy")      \
-                                                                            \
   develop(bool, G1Gen, true,                                                \
           "If true, it will enable the generational G1")                    \
                                                                             \
@@ -70,7 +67,7 @@
   develop(intx, G1PausesBtwnConcMark, -1,                                   \
           "If positive, fixed number of pauses between conc markings")      \
                                                                             \
-  diagnostic(bool, G1SummarizeConcurrentMark, false,                        \
+  diagnostic(bool, G1SummarizeConcMark, false,                              \
           "Summarize concurrent mark info")                                 \
                                                                             \
   diagnostic(bool, G1SummarizeRSetStats, false,                             \
@@ -85,12 +82,9 @@
   diagnostic(bool, G1SummarizeZFStats, false,                               \
           "Summarize zero-filling info")                                    \
                                                                             \
-  diagnostic(bool, G1TraceConcurrentRefinement, false,                      \
+  diagnostic(bool, G1TraceConcRefinement, false,                            \
           "Trace G1 concurrent refinement")                                 \
                                                                             \
-  product(intx, G1MarkStackSize, 2 * 1024 * 1024,                           \
-          "Size of the mark stack for concurrent marking.")                 \
-                                                                            \
   product(intx, G1MarkRegionStackSize, 1024 * 1024,                         \
           "Size of the region stack for concurrent marking.")               \
                                                                             \
@@ -100,20 +94,13 @@
   develop(intx, G1ConcZFMaxRegions, 1,                                      \
           "Stop zero-filling when # of zf'd regions reaches")               \
                                                                             \
-  product(intx, G1SteadyStateUsed, 90,                                      \
-          "If non-0, try to maintain 'used' at this pct (of max)")          \
-                                                                            \
-  product(intx, G1SteadyStateUsedDelta, 30,                                 \
-          "If G1SteadyStateUsed is non-0, then do pause this number of "    \
-          "of percentage points earlier if no marking is in progress.")     \
-                                                                            \
   develop(bool, G1SATBBarrierPrintNullPreVals, false,                       \
           "If true, count frac of ptr writes with null pre-vals.")          \
                                                                             \
-  product(intx, G1SATBLogBufferSize, 1*K,                                   \
+  product(intx, G1SATBBufferSize, 1*K,                                      \
           "Number of entries in an SATB log buffer.")                       \
                                                                             \
-  product(intx, G1SATBProcessCompletedThreshold, 20,                        \
+  develop(intx, G1SATBProcessCompletedThreshold, 20,                        \
           "Number of completed buffers that triggers log processing.")      \
                                                                             \
   develop(intx, G1ExtraRegionSurvRate, 33,                                  \
@@ -127,7 +114,7 @@
   develop(bool, G1SATBPrintStubs, false,                                    \
           "If true, print generated stubs for the SATB barrier")            \
                                                                             \
-  product(intx, G1ExpandByPercentOfAvailable, 20,                           \
+  experimental(intx, G1ExpandByPercentOfAvailable, 20,                      \
           "When expanding, % of uncommitted space to claim.")               \
                                                                             \
   develop(bool, G1RSBarrierRegionFilter, true,                              \
@@ -165,36 +152,36 @@
   product(intx, G1UpdateBufferSize, 256,                                    \
           "Size of an update buffer")                                       \
                                                                             \
-  product(intx, G1ConcRefineYellowZone, 0,                                  \
+  product(intx, G1ConcRefinementYellowZone, 0,                              \
           "Number of enqueued update buffers that will "                    \
           "trigger concurrent processing. Will be selected ergonomically "  \
           "by default.")                                                    \
                                                                             \
-  product(intx, G1ConcRefineRedZone, 0,                                     \
+  product(intx, G1ConcRefinementRedZone, 0,                                 \
           "Maximum number of enqueued update buffers before mutator "       \
           "threads start processing new ones instead of enqueueing them. "  \
           "Will be selected ergonomically by default. Zero will disable "   \
           "concurrent processing.")                                         \
                                                                             \
-  product(intx, G1ConcRefineGreenZone, 0,                                   \
+  product(intx, G1ConcRefinementGreenZone, 0,                               \
           "The number of update buffers that are left in the queue by the " \
           "concurrent processing threads. Will be selected ergonomically "  \
           "by default.")                                                    \
                                                                             \
-  product(intx, G1ConcRefineServiceInterval, 300,                           \
+  product(intx, G1ConcRefinementServiceIntervalMillis, 300,                 \
           "The last concurrent refinement thread wakes up every "           \
           "specified number of milliseconds to do miscellaneous work.")     \
                                                                             \
-  product(intx, G1ConcRefineThresholdStep, 0,                               \
+  product(intx, G1ConcRefinementThresholdStep, 0,                           \
           "Each time the rset update queue increases by this amount "       \
           "activate the next refinement thread if available. "              \
           "Will be selected ergonomically by default.")                     \
                                                                             \
-  product(intx, G1RSUpdatePauseFractionPercent, 10,                         \
+  product(intx, G1RSetUpdatingPauseTimePercent, 10,                         \
           "A target percentage of time that is allowed to be spend on "     \
           "process RS update buffers during the collection pause.")         \
                                                                             \
-  product(bool, G1AdaptiveConcRefine, true,                                 \
+  product(bool, G1UseAdaptiveConcRefinement, true,                          \
           "Select green, yellow and red zones adaptively to meet the "      \
           "the pause requirements.")                                        \
                                                                             \
@@ -245,15 +232,15 @@
           "the number of regions for which we'll print a surv rate "        \
           "summary.")                                                       \
                                                                             \
-  product(bool, G1UseScanOnlyPrefix, false,                                 \
+  develop(bool, G1UseScanOnlyPrefix, false,                                 \
           "It determines whether the system will calculate an optimum "     \
           "scan-only set.")                                                 \
                                                                             \
-  product(intx, G1MinReservePercent, 10,                                    \
+  product(intx, G1ReservePercent, 10,                                       \
           "It determines the minimum reserve we should have in the heap "   \
           "to minimize the probability of promotion failure.")              \
                                                                             \
-  diagnostic(bool, G1PrintRegions, false,                                   \
+  diagnostic(bool, G1PrintHeapRegions, false,                               \
           "If set G1 will print information on which regions are being "    \
           "allocated and which are reclaimed.")                             \
                                                                             \
@@ -263,9 +250,6 @@
   develop(bool, G1HRRSFlushLogBuffersOnVerify, false,                       \
           "Forces flushing of log buffers before verification.")            \
                                                                             \
-  product(bool, G1UseSurvivorSpaces, true,                                  \
-          "When true, use survivor space.")                                 \
-                                                                            \
   develop(bool, G1FailOnFPError, false,                                     \
           "When set, G1 will fail when it encounters an FP 'error', "       \
           "so as to allow debugging")                                       \
@@ -280,21 +264,21 @@
           "If non-0 is the size of the G1 survivor space, "                 \
           "otherwise SurvivorRatio is used to determine the size")          \
                                                                             \
-  product(bool, G1ForgetfulMMUTracker, false,                               \
+  product(bool, G1UseFixedWindowMMUTracker, false,                          \
           "If the MMU tracker's memory is full, forget the oldest entry")   \
                                                                             \
   product(uintx, G1HeapRegionSize, 0,                                       \
           "Size of the G1 regions.")                                        \
                                                                             \
-  experimental(bool, G1ParallelRSetUpdatingEnabled, false,                  \
+  experimental(bool, G1UseParallelRSetUpdating, false,                      \
           "Enables the parallelization of remembered set updating "         \
           "during evacuation pauses")                                       \
                                                                             \
-  experimental(bool, G1ParallelRSetScanningEnabled, false,                  \
+  experimental(bool, G1UseParallelRSetScanning, false,                      \
           "Enables the parallelization of remembered set scanning "         \
           "during evacuation pauses")                                       \
                                                                             \
-  product(uintx, G1ParallelRSetThreads, 0,                                  \
+  product(uintx, G1ConcRefinementThreads, 0,                                \
           "If non-0 is the number of parallel rem set update threads, "     \
           "otherwise the value is determined ergonomically.")               \
                                                                             \
--- a/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -25,8 +25,8 @@
 # include "incls/_precompiled.incl"
 # include "incls/_ptrQueue.cpp.incl"
 
-PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm) :
-  _qset(qset_), _buf(NULL), _index(0), _active(false),
+PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm, bool active) :
+  _qset(qset_), _buf(NULL), _index(0), _active(active),
   _perm(perm), _lock(NULL)
 {}
 
--- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -62,7 +62,7 @@
 public:
   // Initialize this queue to contain a null buffer, and be part of the
   // given PtrQueueSet.
-  PtrQueue(PtrQueueSet*, bool perm = false);
+  PtrQueue(PtrQueueSet*, bool perm = false, bool active = false);
   // Release any contained resources.
   void flush();
   // Calls flush() when destroyed.
@@ -101,6 +101,8 @@
     }
   }
 
+  bool is_active() { return _active; }
+
   static int byte_index_to_index(int ind) {
     assert((ind % oopSize) == 0, "Invariant.");
     return ind / oopSize;
@@ -257,7 +259,7 @@
   bool process_completed_buffers() { return _process_completed; }
   void set_process_completed(bool x) { _process_completed = x; }
 
-  bool active() { return _all_active; }
+  bool is_active() { return _all_active; }
 
   // Set the buffer size.  Should be called before any "enqueue" operation
   // can be called.  And should only be called once.
--- a/src/share/vm/gc_implementation/g1/satbQueue.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/satbQueue.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -82,9 +82,57 @@
   t->satb_mark_queue().handle_zero_index();
 }
 
-void SATBMarkQueueSet::set_active_all_threads(bool b) {
+#ifdef ASSERT
+void SATBMarkQueueSet::dump_active_values(JavaThread* first,
+                                          bool expected_active) {
+  gclog_or_tty->print_cr("SATB queue active values for Java Threads");
+  gclog_or_tty->print_cr(" SATB queue set: active is %s",
+                         (is_active()) ? "TRUE" : "FALSE");
+  gclog_or_tty->print_cr(" expected_active is %s",
+                         (expected_active) ? "TRUE" : "FALSE");
+  for (JavaThread* t = first; t; t = t->next()) {
+    bool active = t->satb_mark_queue().is_active();
+    gclog_or_tty->print_cr("  thread %s, active is %s",
+                           t->name(), (active) ? "TRUE" : "FALSE");
+  }
+}
+#endif // ASSERT
+
+void SATBMarkQueueSet::set_active_all_threads(bool b,
+                                              bool expected_active) {
+  assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
+  JavaThread* first = Threads::first();
+
+#ifdef ASSERT
+  if (_all_active != expected_active) {
+    dump_active_values(first, expected_active);
+
+    // I leave this here as a guarantee, instead of an assert, so
+    // that it will still be compiled in if we choose to uncomment
+    // the #ifdef ASSERT in a product build. The whole block is
+    // within an #ifdef ASSERT so the guarantee will not be compiled
+    // in a product build anyway.
+    guarantee(false,
+              "SATB queue set has an unexpected active value");
+  }
+#endif // ASSERT
   _all_active = b;
-  for(JavaThread* t = Threads::first(); t; t = t->next()) {
+
+  for (JavaThread* t = first; t; t = t->next()) {
+#ifdef ASSERT
+    bool active = t->satb_mark_queue().is_active();
+    if (active != expected_active) {
+      dump_active_values(first, expected_active);
+
+      // I leave this here as a guarantee, instead of an assert, so
+      // that it will still be compiled in if we choose to uncomment
+      // the #ifdef ASSERT in a product build. The whole block is
+      // within an #ifdef ASSERT so the guarantee will not be compiled
+      // in a product build anyway.
+      guarantee(false,
+                "thread has an unexpected active value in its SATB queue");
+    }
+#endif // ASSERT
     t->satb_mark_queue().set_active(b);
   }
 }
--- a/src/share/vm/gc_implementation/g1/satbQueue.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/satbQueue.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -29,8 +29,7 @@
 class ObjPtrQueue: public PtrQueue {
 public:
   ObjPtrQueue(PtrQueueSet* qset_, bool perm = false) :
-    PtrQueue(qset_, perm)
-  {}
+    PtrQueue(qset_, perm, qset_->is_active()) { }
   // Apply the closure to all elements, and reset the index to make the
   // buffer empty.
   void apply_closure(ObjectClosure* cl);
@@ -55,6 +54,9 @@
   // is ignored.
   bool apply_closure_to_completed_buffer_work(bool par, int worker);
 
+#ifdef ASSERT
+  void dump_active_values(JavaThread* first, bool expected_active);
+#endif // ASSERT
 
 public:
   SATBMarkQueueSet();
@@ -65,9 +67,11 @@
 
   static void handle_zero_index_for_thread(JavaThread* t);
 
-  // Apply "set_active(b)" to all thread tloq's.  Should be called only
-  // with the world stopped.
-  void set_active_all_threads(bool b);
+  // Apply "set_active(b)" to all Java threads' SATB queues. It should be
+  // called only with the world stopped. The method will assert that the
+  // SATB queues of all threads it visits, as well as the SATB queue
+  // set itself, has an active value same as expected_active.
+  void set_active_all_threads(bool b, bool expected_active);
 
   // Register "blk" as "the closure" for all queues.  Only one such closure
   // is allowed.  The "apply_closure_to_completed_buffer" method will apply
--- a/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Mon Apr 19 20:41:10 2010 -0700
@@ -175,6 +175,7 @@
 psAdaptiveSizePolicy.hpp		adaptiveSizePolicy.hpp
 
 psCompactionManager.cpp                 gcTaskManager.hpp
+psCompactionManager.cpp                 objArrayKlass.inline.hpp
 psCompactionManager.cpp                 objectStartArray.hpp
 psCompactionManager.cpp                 oop.hpp
 psCompactionManager.cpp                 oop.inline.hpp
@@ -189,6 +190,9 @@
 psCompactionManager.hpp                 allocation.hpp
 psCompactionManager.hpp                 taskqueue.hpp
 
+psCompactionManager.inline.hpp		psCompactionManager.hpp
+psCompactionManager.inline.hpp		psParallelCompact.hpp
+
 psGCAdaptivePolicyCounters.hpp		gcAdaptivePolicyCounters.hpp
 psGCAdaptivePolicyCounters.hpp          gcPolicyCounters.hpp
 psGCAdaptivePolicyCounters.hpp          psAdaptiveSizePolicy.hpp
@@ -379,12 +383,12 @@
 pcTasks.cpp                             jniHandles.hpp
 pcTasks.cpp                             jvmtiExport.hpp
 pcTasks.cpp                             management.hpp
+pcTasks.cpp                             objArrayKlass.inline.hpp
 pcTasks.cpp                             psParallelCompact.hpp
 pcTasks.cpp                             pcTasks.hpp
 pcTasks.cpp                             oop.inline.hpp
 pcTasks.cpp                             oop.pcgc.inline.hpp
 pcTasks.cpp                             systemDictionary.hpp
-pcTasks.cpp                             taskqueue.hpp
 pcTasks.cpp                             thread.hpp
 pcTasks.cpp                             universe.hpp
 pcTasks.cpp                             vmThread.hpp
--- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -48,7 +48,7 @@
     _vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
 
   // Do the real work
-  cm->drain_marking_stacks(&mark_and_push_closure);
+  cm->follow_marking_stacks();
 }
 
 
@@ -118,7 +118,7 @@
   }
 
   // Do the real work
-  cm->drain_marking_stacks(&mark_and_push_closure);
+  cm->follow_marking_stacks();
   // cm->deallocate_stacks();
 }
 
@@ -196,17 +196,19 @@
   PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
 
   oop obj = NULL;
+  ObjArrayTask task;
   int random_seed = 17;
-  while(true) {
-    if (ParCompactionManager::steal(which, &random_seed, obj)) {
+  do {
+    while (ParCompactionManager::steal_objarray(which, &random_seed, task)) {
+      objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+      k->oop_follow_contents(cm, task.obj(), task.index());
+      cm->follow_marking_stacks();
+    }
+    while (ParCompactionManager::steal(which, &random_seed, obj)) {
       obj->follow_contents(cm);
-      cm->drain_marking_stacks(&mark_and_push_closure);
-    } else {
-      if (terminator()->offer_termination()) {
-        break;
-      }
+      cm->follow_marking_stacks();
     }
-  }
+  } while (!terminator()->offer_termination());
 }
 
 //
--- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -28,6 +28,8 @@
 PSOldGen*            ParCompactionManager::_old_gen = NULL;
 ParCompactionManager**  ParCompactionManager::_manager_array = NULL;
 OopTaskQueueSet*     ParCompactionManager::_stack_array = NULL;
+ParCompactionManager::ObjArrayTaskQueueSet*
+  ParCompactionManager::_objarray_queues = NULL;
 ObjectStartArray*    ParCompactionManager::_start_array = NULL;
 ParMarkBitMap*       ParCompactionManager::_mark_bitmap = NULL;
 RegionTaskQueueSet*   ParCompactionManager::_region_array = NULL;
@@ -46,6 +48,11 @@
 
   // We want the overflow stack to be permanent
   _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true);
+
+  _objarray_queue.initialize();
+  _objarray_overflow_stack =
+    new (ResourceObj::C_HEAP) ObjArrayOverflowStack(10, true);
+
 #ifdef USE_RegionTaskQueueWithOverflow
   region_stack()->initialize();
 #else
@@ -69,6 +76,7 @@
 
 ParCompactionManager::~ParCompactionManager() {
   delete _overflow_stack;
+  delete _objarray_overflow_stack;
   delete _revisit_klass_stack;
   delete _revisit_mdo_stack;
   // _manager_array and _stack_array are statics
@@ -86,18 +94,21 @@
 
   assert(_manager_array == NULL, "Attempt to initialize twice");
   _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 );
-  guarantee(_manager_array != NULL, "Could not initialize promotion manager");
+  guarantee(_manager_array != NULL, "Could not allocate manager_array");
 
   _stack_array = new OopTaskQueueSet(parallel_gc_threads);
-  guarantee(_stack_array != NULL, "Count not initialize promotion manager");
+  guarantee(_stack_array != NULL, "Could not allocate stack_array");
+  _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads);
+  guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues");
   _region_array = new RegionTaskQueueSet(parallel_gc_threads);
-  guarantee(_region_array != NULL, "Count not initialize promotion manager");
+  guarantee(_region_array != NULL, "Could not allocate region_array");
 
   // Create and register the ParCompactionManager(s) for the worker threads.
   for(uint i=0; i<parallel_gc_threads; i++) {
     _manager_array[i] = new ParCompactionManager();
     guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager");
     stack_array()->register_queue(i, _manager_array[i]->marking_stack());
+    _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_queue);
 #ifdef USE_RegionTaskQueueWithOverflow
     region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue());
 #else
@@ -203,36 +214,30 @@
   }
 }
 
-void ParCompactionManager::drain_marking_stacks(OopClosure* blk) {
-#ifdef ASSERT
-  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
-  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
-  MutableSpace* to_space = heap->young_gen()->to_space();
-  MutableSpace* old_space = heap->old_gen()->object_space();
-  MutableSpace* perm_space = heap->perm_gen()->object_space();
-#endif /* ASSERT */
-
-
+void ParCompactionManager::follow_marking_stacks() {
   do {
-
-    // Drain overflow stack first, so other threads can steal from
-    // claimed stack while we work.
-    while(!overflow_stack()->is_empty()) {
-      oop obj = overflow_stack()->pop();
+    // Drain the overflow stack first, to allow stealing from the marking stack.
+    oop obj;
+    while (!overflow_stack()->is_empty()) {
+      overflow_stack()->pop()->follow_contents(this);
+    }
+    while (marking_stack()->pop_local(obj)) {
       obj->follow_contents(this);
     }
 
-    oop obj;
-    // obj is a reference!!!
-    while (marking_stack()->pop_local(obj)) {
-      // It would be nice to assert about the type of objects we might
-      // pop, but they can come from anywhere, unfortunately.
-      obj->follow_contents(this);
+    // Process ObjArrays one at a time to avoid marking stack bloat.
+    ObjArrayTask task;
+    if (!_objarray_overflow_stack->is_empty()) {
+      task = _objarray_overflow_stack->pop();
+      objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+      k->oop_follow_contents(this, task.obj(), task.index());
+    } else if (_objarray_queue.pop_local(task)) {
+      objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+      k->oop_follow_contents(this, task.obj(), task.index());
     }
-  } while((marking_stack()->size() != 0) || (overflow_stack()->length() != 0));
+  } while (!marking_stacks_empty());
 
-  assert(marking_stack()->size() == 0, "Sanity");
-  assert(overflow_stack()->length() == 0, "Sanity");
+  assert(marking_stacks_empty(), "Sanity");
 }
 
 void ParCompactionManager::drain_region_overflow_stack() {
--- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -22,18 +22,6 @@
  *
  */
 
-//
-// psPromotionManager is used by a single thread to manage object survival
-// during a scavenge. The promotion manager contains thread local data only.
-//
-// NOTE! Be carefull when allocating the stacks on cheap. If you are going
-// to use a promotion manager in more than one thread, the stacks MUST be
-// on cheap. This can lead to memory leaks, though, as they are not auto
-// deallocated.
-//
-// FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate!
-//
-
 // Move to some global location
 #define HAS_BEEN_MOVED 0x1501d01d
 // End move to some global location
@@ -46,8 +34,6 @@
 class ParallelCompactData;
 class ParMarkBitMap;
 
-// Move to it's own file if this works out.
-
 class ParCompactionManager : public CHeapObj {
   friend class ParallelTaskTerminator;
   friend class ParMarkBitMap;
@@ -72,14 +58,27 @@
 // ------------------------  End don't putback if not needed
 
  private:
+  // 32-bit:  4K * 8 = 32KiB; 64-bit:  8K * 16 = 128KiB
+  #define OBJARRAY_QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13))
+  typedef GenericTaskQueue<ObjArrayTask, OBJARRAY_QUEUE_SIZE> ObjArrayTaskQueue;
+  typedef GenericTaskQueueSet<ObjArrayTaskQueue> ObjArrayTaskQueueSet;
+  #undef OBJARRAY_QUEUE_SIZE
+
   static ParCompactionManager** _manager_array;
   static OopTaskQueueSet*       _stack_array;
+  static ObjArrayTaskQueueSet*  _objarray_queues;
   static ObjectStartArray*      _start_array;
   static RegionTaskQueueSet*    _region_array;
   static PSOldGen*              _old_gen;
 
+private:
   OopTaskQueue                  _marking_stack;
   GrowableArray<oop>*           _overflow_stack;
+
+  typedef GrowableArray<ObjArrayTask> ObjArrayOverflowStack;
+  ObjArrayTaskQueue             _objarray_queue;
+  ObjArrayOverflowStack*        _objarray_overflow_stack;
+
   // Is there a way to reuse the _marking_stack for the
   // saving empty regions?  For now just create a different
   // type of TaskQueue.
@@ -128,8 +127,8 @@
   // Pushes onto the region stack.  If the region stack is full,
   // pushes onto the region overflow stack.
   void region_stack_push(size_t region_index);
- public:
 
+public:
   Action action() { return _action; }
   void set_action(Action v) { _action = v; }
 
@@ -163,6 +162,8 @@
   // Get a oop for scanning.  If returns null, no oop were found.
   oop retrieve_for_scanning();
 
+  inline void push_objarray(oop obj, size_t index);
+
   // Save region for later processing.  Must not fail.
   void save_for_processing(size_t region_index);
   // Get a region for processing.  If returns null, no region were found.
@@ -175,12 +176,17 @@
     return stack_array()->steal(queue_num, seed, t);
   }
 
+  static bool steal_objarray(int queue_num, int* seed, ObjArrayTask& t) {
+    return _objarray_queues->steal(queue_num, seed, t);
+  }
+
   static bool steal(int queue_num, int* seed, RegionTask& t) {
     return region_array()->steal(queue_num, seed, t);
   }
 
-  // Process tasks remaining on any stack
-  void drain_marking_stacks(OopClosure *blk);
+  // Process tasks remaining on any marking stack
+  void follow_marking_stacks();
+  inline bool marking_stacks_empty() const;
 
   // Process tasks remaining on any stack
   void drain_region_stacks();
@@ -200,3 +206,8 @@
     "out of range manager_array access");
   return _manager_array[index];
 }
+
+bool ParCompactionManager::marking_stacks_empty() const {
+  return _marking_stack.size() == 0 && _overflow_stack->is_empty() &&
+    _objarray_queue.size() == 0 && _objarray_overflow_stack->is_empty();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.inline.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+void ParCompactionManager::push_objarray(oop obj, size_t index)
+{
+  ObjArrayTask task(obj, index);
+  assert(task.is_valid(), "bad ObjArrayTask");
+  if (!_objarray_queue.push(task)) {
+    _objarray_overflow_stack->push(task);
+  }
+}
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -479,6 +479,7 @@
   _preserved_oop_stack = NULL;
 
   _marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
+  _objarray_stack = new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true);
 
   int size = SystemDictionary::number_of_classes() * 2;
   _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true);
@@ -497,6 +498,7 @@
   }
 
   delete _marking_stack;
+  delete _objarray_stack;
   delete _revisit_klass_stack;
   delete _revisit_mdo_stack;
 }
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -785,7 +785,7 @@
 void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p)       { adjust_pointer(p, _is_root); }
 void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
 
-void PSParallelCompact::FollowStackClosure::do_void() { follow_stack(_compaction_manager); }
+void PSParallelCompact::FollowStackClosure::do_void() { _compaction_manager->follow_marking_stacks(); }
 
 void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p)       { mark_and_push(_compaction_manager, p); }
 void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); }
@@ -2376,7 +2376,7 @@
   // Follow code cache roots.
   CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure,
                           purged_class);
-  follow_stack(cm); // Flush marking stack.
+  cm->follow_marking_stacks(); // Flush marking stack.
 
   // Update subklass/sibling/implementor links of live klasses
   // revisit_klass_stack is used in follow_weak_klass_links().
@@ -2389,8 +2389,7 @@
   SymbolTable::unlink(is_alive_closure());
   StringTable::unlink(is_alive_closure());
 
-  assert(cm->marking_stack()->size() == 0, "stack should be empty by now");
-  assert(cm->overflow_stack()->is_empty(), "stack should be empty by now");
+  assert(cm->marking_stacks_empty(), "marking stacks should be empty");
 }
 
 // This should be moved to the shared markSweep code!
@@ -2709,22 +2708,6 @@
   young_gen->move_and_update(cm);
 }
 
-
-void PSParallelCompact::follow_stack(ParCompactionManager* cm) {
-  while(!cm->overflow_stack()->is_empty()) {
-    oop obj = cm->overflow_stack()->pop();
-    obj->follow_contents(cm);
-  }
-
-  oop obj;
-  // obj is a reference!!!
-  while (cm->marking_stack()->pop_local(obj)) {
-    // It would be nice to assert about the type of objects we might
-    // pop, but they can come from anywhere, unfortunately.
-    obj->follow_contents(cm);
-  }
-}
-
 void
 PSParallelCompact::follow_weak_klass_links() {
   // All klasses on the revisit stack are marked at this point.
@@ -2745,7 +2728,7 @@
         &keep_alive_closure);
     }
     // revisit_klass_stack is cleared in reset()
-    follow_stack(cm);
+    cm->follow_marking_stacks();
   }
 }
 
@@ -2776,7 +2759,7 @@
       rms->at(j)->follow_weak_refs(is_alive_closure());
     }
     // revisit_mdo_stack is cleared in reset()
-    follow_stack(cm);
+    cm->follow_marking_stacks();
   }
 }
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -901,7 +901,6 @@
   // Mark live objects
   static void marking_phase(ParCompactionManager* cm,
                             bool maximum_heap_compaction);
-  static void follow_stack(ParCompactionManager* cm);
   static void follow_weak_klass_links();
   static void follow_mdo_weak_refs();
 
@@ -1276,7 +1275,7 @@
       }
     }
   }
-  follow_stack(cm);
+  cm->follow_marking_stacks();
 }
 
 template <class T>
--- a/src/share/vm/gc_implementation/shared/markSweep.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/shared/markSweep.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -25,8 +25,9 @@
 #include "incls/_precompiled.incl"
 #include "incls/_markSweep.cpp.incl"
 
-GrowableArray<oop>*     MarkSweep::_marking_stack       = NULL;
-GrowableArray<Klass*>*  MarkSweep::_revisit_klass_stack = NULL;
+GrowableArray<oop>*          MarkSweep::_marking_stack = NULL;
+GrowableArray<ObjArrayTask>* MarkSweep::_objarray_stack = NULL;
+GrowableArray<Klass*>*       MarkSweep::_revisit_klass_stack = NULL;
 GrowableArray<DataLayout*>*  MarkSweep::_revisit_mdo_stack = NULL;
 
 GrowableArray<oop>*     MarkSweep::_preserved_oop_stack = NULL;
@@ -104,11 +105,19 @@
 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
 
 void MarkSweep::follow_stack() {
-  while (!_marking_stack->is_empty()) {
-    oop obj = _marking_stack->pop();
-    assert (obj->is_gc_marked(), "p must be marked");
-    obj->follow_contents();
-  }
+  do {
+    while (!_marking_stack->is_empty()) {
+      oop obj = _marking_stack->pop();
+      assert (obj->is_gc_marked(), "p must be marked");
+      obj->follow_contents();
+    }
+    // Process ObjArrays one at a time to avoid marking stack bloat.
+    if (!_objarray_stack->is_empty()) {
+      ObjArrayTask task = _objarray_stack->pop();
+      objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
+      k->oop_follow_contents(task.obj(), task.index());
+    }
+  } while (!_marking_stack->is_empty() || !_objarray_stack->is_empty());
 }
 
 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
--- a/src/share/vm/gc_implementation/shared/markSweep.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/shared/markSweep.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -110,8 +110,9 @@
   // Vars
   //
  protected:
-  // Traversal stack used during phase1
+  // Traversal stacks used during phase1
   static GrowableArray<oop>*             _marking_stack;
+  static GrowableArray<ObjArrayTask>*    _objarray_stack;
   // Stack for live klasses to revisit at end of marking phase
   static GrowableArray<Klass*>*          _revisit_klass_stack;
   // Set (stack) of MDO's to revisit at end of marking phase
@@ -188,6 +189,7 @@
   template <class T> static inline void mark_and_follow(T* p);
   // Check mark and maybe push on marking stack
   template <class T> static inline void mark_and_push(T* p);
+  static inline void push_objarray(oop obj, size_t index);
 
   static void follow_stack();   // Empty marking stack.
 
--- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -77,6 +77,12 @@
   }
 }
 
+void MarkSweep::push_objarray(oop obj, size_t index) {
+  ObjArrayTask task(obj, index);
+  assert(task.is_valid(), "bad ObjArrayTask");
+  _objarray_stack->push(task);
+}
+
 template <class T> inline void MarkSweep::adjust_pointer(T* p, bool isroot) {
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop)) {
--- a/src/share/vm/includeDB_compiler1	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/includeDB_compiler1	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 //
-// Copyright 1999-2009 Sun Microsystems, Inc.  All Rights Reserved.
+// Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -246,6 +246,7 @@
 c1_LIRGenerator.cpp                     c1_LIRGenerator.hpp
 c1_LIRGenerator.cpp                     c1_ValueStack.hpp
 c1_LIRGenerator.cpp                     ciArrayKlass.hpp
+c1_LIRGenerator.cpp                     ciCPCache.hpp
 c1_LIRGenerator.cpp                     ciInstance.hpp
 c1_LIRGenerator.cpp                     heapRegion.hpp
 c1_LIRGenerator.cpp                     sharedRuntime.hpp
--- a/src/share/vm/includeDB_core	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/includeDB_core	Mon Apr 19 20:41:10 2010 -0700
@@ -176,6 +176,7 @@
 arguments.cpp                           oop.inline.hpp
 arguments.cpp                           os_<os_family>.inline.hpp
 arguments.cpp                           referenceProcessor.hpp
+arguments.cpp                           taskqueue.hpp
 arguments.cpp                           universe.inline.hpp
 arguments.cpp                           vm_version_<arch>.hpp
 
@@ -540,6 +541,7 @@
 
 ciCPCache.cpp                           cpCacheOop.hpp
 ciCPCache.cpp                           ciCPCache.hpp
+ciCPCache.cpp                           ciUtilities.hpp
 
 ciCPCache.hpp                           ciClassList.hpp
 ciCPCache.hpp                           ciObject.hpp
@@ -1021,6 +1023,7 @@
 codeCache.cpp                           codeCache.hpp
 codeCache.cpp                           dependencies.hpp
 codeCache.cpp                           gcLocker.hpp
+codeCache.cpp                           handles.inline.hpp
 codeCache.cpp                           icache.hpp
 codeCache.cpp                           iterator.hpp
 codeCache.cpp                           java.hpp
@@ -2014,6 +2017,7 @@
 init.cpp                                icBuffer.hpp
 init.cpp                                icache.hpp
 init.cpp                                init.hpp
+init.cpp                                methodHandles.hpp
 init.cpp                                safepoint.hpp
 init.cpp                                sharedRuntime.hpp
 init.cpp                                universe.hpp
@@ -2022,6 +2026,7 @@
 
 instanceKlass.cpp                       collectedHeap.inline.hpp
 instanceKlass.cpp                       compileBroker.hpp
+instanceKlass.cpp                       dtrace.hpp
 instanceKlass.cpp                       fieldDescriptor.hpp
 instanceKlass.cpp                       genOopClosures.inline.hpp
 instanceKlass.cpp                       handles.inline.hpp
@@ -2481,6 +2486,7 @@
 jvm.cpp                                 collectedHeap.inline.hpp
 jvm.cpp                                 copy.hpp
 jvm.cpp                                 defaultStream.hpp
+jvm.cpp                                 dtrace.hpp
 jvm.cpp                                 dtraceJSDT.hpp
 jvm.cpp                                 events.hpp
 jvm.cpp                                 handles.inline.hpp
@@ -2722,8 +2728,10 @@
 
 markSweep.cpp                           compileBroker.hpp
 markSweep.cpp                           methodDataOop.hpp
+markSweep.cpp				objArrayKlass.inline.hpp
 
 markSweep.hpp                           collectedHeap.hpp
+markSweep.hpp				taskqueue.hpp
 
 memRegion.cpp                           globals.hpp
 memRegion.cpp                           memRegion.hpp
@@ -2868,6 +2876,7 @@
 methodHandles.cpp                       oopFactory.hpp
 methodHandles.cpp                       reflection.hpp
 methodHandles.cpp                       signature.hpp
+methodHandles.cpp                       stubRoutines.hpp
 methodHandles.cpp                       symbolTable.hpp
 
 methodHandles_<arch>.cpp                allocation.inline.hpp
@@ -3052,8 +3061,10 @@
 objArrayKlass.cpp                       genOopClosures.inline.hpp
 objArrayKlass.cpp                       handles.inline.hpp
 objArrayKlass.cpp                       instanceKlass.hpp
+objArrayKlass.cpp                       markSweep.inline.hpp
 objArrayKlass.cpp                       mutexLocker.hpp
 objArrayKlass.cpp                       objArrayKlass.hpp
+objArrayKlass.cpp                       objArrayKlass.inline.hpp
 objArrayKlass.cpp                       objArrayKlassKlass.hpp
 objArrayKlass.cpp                       objArrayOop.hpp
 objArrayKlass.cpp                       oop.inline.hpp
@@ -3064,11 +3075,12 @@
 objArrayKlass.cpp                       universe.inline.hpp
 objArrayKlass.cpp                       vmSymbols.hpp
 
-
 objArrayKlass.hpp                       arrayKlass.hpp
 objArrayKlass.hpp                       instanceKlass.hpp
 objArrayKlass.hpp                       specialized_oop_closures.hpp
 
+objArrayKlass.inline.hpp		objArrayKlass.hpp
+
 objArrayKlassKlass.cpp                  collectedHeap.inline.hpp
 objArrayKlassKlass.cpp                  instanceKlass.hpp
 objArrayKlassKlass.cpp                  javaClasses.hpp
@@ -4094,6 +4106,7 @@
 task.hpp                                top.hpp
 
 taskqueue.cpp                           debug.hpp
+taskqueue.cpp				oop.inline.hpp
 taskqueue.cpp                           os.hpp
 taskqueue.cpp                           taskqueue.hpp
 taskqueue.cpp                           thread_<os_family>.inline.hpp
@@ -4447,6 +4460,7 @@
 
 unsafe.cpp                              allocation.inline.hpp
 unsafe.cpp                              copy.hpp
+unsafe.cpp                              dtrace.hpp
 unsafe.cpp                              globals.hpp
 unsafe.cpp                              interfaceSupport.hpp
 unsafe.cpp                              jni.h
@@ -4618,6 +4632,7 @@
 
 vmThread.cpp                            collectedHeap.hpp
 vmThread.cpp                            compileBroker.hpp
+vmThread.cpp                            dtrace.hpp
 vmThread.cpp                            events.hpp
 vmThread.cpp                            interfaceSupport.hpp
 vmThread.cpp                            methodOop.hpp
--- a/src/share/vm/includeDB_gc_parallel	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/includeDB_gc_parallel	Mon Apr 19 20:41:10 2010 -0700
@@ -115,10 +115,14 @@
 objArrayKlass.cpp                       g1CollectedHeap.inline.hpp
 objArrayKlass.cpp                       g1OopClosures.inline.hpp
 objArrayKlass.cpp                       oop.pcgc.inline.hpp
+objArrayKlass.cpp                       psCompactionManager.hpp
 objArrayKlass.cpp                       psPromotionManager.inline.hpp
 objArrayKlass.cpp                       psScavenge.inline.hpp
 objArrayKlass.cpp                       parOopClosures.inline.hpp
 
+objArrayKlass.inline.hpp		psCompactionManager.inline.hpp
+objArrayKlass.inline.hpp		psParallelCompact.hpp
+
 oop.pcgc.inline.hpp                     parNewGeneration.hpp
 oop.pcgc.inline.hpp                     parallelScavengeHeap.hpp
 oop.pcgc.inline.hpp                     psCompactionManager.hpp
--- a/src/share/vm/memory/genMarkSweep.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/memory/genMarkSweep.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -159,6 +159,7 @@
   _preserved_oop_stack = NULL;
 
   _marking_stack       = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
+  _objarray_stack      = new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true);
 
   int size = SystemDictionary::number_of_classes() * 2;
   _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true);
@@ -194,7 +195,6 @@
 
 
 void GenMarkSweep::deallocate_stacks() {
-
   if (!UseG1GC) {
     GenCollectedHeap* gch = GenCollectedHeap::heap();
     gch->release_scratch();
@@ -208,6 +208,7 @@
   }
 
   delete _marking_stack;
+  delete _objarray_stack;
   delete _revisit_klass_stack;
   delete _revisit_mdo_stack;
 
--- a/src/share/vm/memory/genOopClosures.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/memory/genOopClosures.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -28,10 +28,10 @@
 class CardTableModRefBS;
 class DefNewGeneration;
 
-template<class E> class GenericTaskQueue;
-typedef GenericTaskQueue<oop> OopTaskQueue;
-template<class E> class GenericTaskQueueSet;
-typedef GenericTaskQueueSet<oop> OopTaskQueueSet;
+template<class E, unsigned int N> class GenericTaskQueue;
+typedef GenericTaskQueue<oop, TASKQUEUE_SIZE> OopTaskQueue;
+template<class T> class GenericTaskQueueSet;
+typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
 
 // Closure for iterating roots from a particular generation
 // Note: all classes deriving from this MUST call this do_barrier
--- a/src/share/vm/oops/instanceKlass.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -25,6 +25,58 @@
 # include "incls/_precompiled.incl"
 # include "incls/_instanceKlass.cpp.incl"
 
+#ifdef DTRACE_ENABLED
+
+HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required,
+  char*, intptr_t, oop, intptr_t);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__concurrent,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__erroneous,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__super__failed,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__clinit,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__error,
+  char*, intptr_t, oop, intptr_t, int);
+HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
+  char*, intptr_t, oop, intptr_t, int);
+
+#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)          \
+  {                                                              \
+    char* data = NULL;                                           \
+    int len = 0;                                                 \
+    symbolOop name = (clss)->name();                             \
+    if (name != NULL) {                                          \
+      data = (char*)name->bytes();                               \
+      len = name->utf8_length();                                 \
+    }                                                            \
+    HS_DTRACE_PROBE4(hotspot, class__initialization__##type,     \
+      data, len, (clss)->class_loader(), thread_type);           \
+  }
+
+#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
+  {                                                              \
+    char* data = NULL;                                           \
+    int len = 0;                                                 \
+    symbolOop name = (clss)->name();                             \
+    if (name != NULL) {                                          \
+      data = (char*)name->bytes();                               \
+      len = name->utf8_length();                                 \
+    }                                                            \
+    HS_DTRACE_PROBE5(hotspot, class__initialization__##type,     \
+      data, len, (clss)->class_loader(), thread_type, wait);     \
+  }
+
+#else //  ndef DTRACE_ENABLED
+
+#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)
+#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait)
+
+#endif //  ndef DTRACE_ENABLED
+
 bool instanceKlass::should_be_initialized() const {
   return !is_initialized();
 }
@@ -292,6 +344,10 @@
   // A class could already be verified, since it has been reflected upon.
   this_oop->link_class(CHECK);
 
+  DTRACE_CLASSINIT_PROBE(required, instanceKlass::cast(this_oop()), -1);
+
+  bool wait = false;
+
   // refer to the JVM book page 47 for description of steps
   // Step 1
   { ObjectLocker ol(this_oop, THREAD);
@@ -303,19 +359,25 @@
     // we might end up throwing IE from link/symbol resolution sites
     // that aren't expected to throw.  This would wreak havoc.  See 6320309.
     while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) {
+        wait = true;
       ol.waitUninterruptibly(CHECK);
     }
 
     // Step 3
-    if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self))
+    if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) {
+      DTRACE_CLASSINIT_PROBE_WAIT(recursive, instanceKlass::cast(this_oop()), -1,wait);
       return;
+    }
 
     // Step 4
-    if (this_oop->is_initialized())
+    if (this_oop->is_initialized()) {
+      DTRACE_CLASSINIT_PROBE_WAIT(concurrent, instanceKlass::cast(this_oop()), -1,wait);
       return;
+    }
 
     // Step 5
     if (this_oop->is_in_error_state()) {
+      DTRACE_CLASSINIT_PROBE_WAIT(erroneous, instanceKlass::cast(this_oop()), -1,wait);
       ResourceMark rm(THREAD);
       const char* desc = "Could not initialize class ";
       const char* className = this_oop->external_name();
@@ -348,6 +410,7 @@
         this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads
         CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, superclass initialization error is thrown below
       }
+      DTRACE_CLASSINIT_PROBE_WAIT(super__failed, instanceKlass::cast(this_oop()), -1,wait);
       THROW_OOP(e());
     }
   }
@@ -356,6 +419,7 @@
   {
     assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
     JavaThread* jt = (JavaThread*)THREAD;
+    DTRACE_CLASSINIT_PROBE_WAIT(clinit, instanceKlass::cast(this_oop()), -1,wait);
     // Timer includes any side effects of class initialization (resolution,
     // etc), but not recursive entry into call_class_initializer().
     PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
@@ -383,6 +447,7 @@
       this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
       CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, class initialization error is thrown below
     }
+    DTRACE_CLASSINIT_PROBE_WAIT(error, instanceKlass::cast(this_oop()), -1,wait);
     if (e->is_a(SystemDictionary::Error_klass())) {
       THROW_OOP(e());
     } else {
@@ -392,6 +457,7 @@
                 &args);
     }
   }
+  DTRACE_CLASSINIT_PROBE_WAIT(end, instanceKlass::cast(this_oop()), -1,wait);
 }
 
 
--- a/src/share/vm/oops/objArrayKlass.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/oops/objArrayKlass.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -314,24 +314,24 @@
 
 void objArrayKlass::oop_follow_contents(oop obj) {
   assert (obj->is_array(), "obj must be array");
-  objArrayOop a = objArrayOop(obj);
-  a->follow_header();
-  ObjArrayKlass_OOP_ITERATE( \
-    a, p, \
-    /* we call mark_and_follow here to avoid excessive marking stack usage */ \
-    MarkSweep::mark_and_follow(p))
+  objArrayOop(obj)->follow_header();
+  if (UseCompressedOops) {
+    objarray_follow_contents<narrowOop>(obj, 0);
+  } else {
+    objarray_follow_contents<oop>(obj, 0);
+  }
 }
 
 #ifndef SERIALGC
 void objArrayKlass::oop_follow_contents(ParCompactionManager* cm,
                                         oop obj) {
-  assert (obj->is_array(), "obj must be array");
-  objArrayOop a = objArrayOop(obj);
-  a->follow_header(cm);
-  ObjArrayKlass_OOP_ITERATE( \
-    a, p, \
-    /* we call mark_and_follow here to avoid excessive marking stack usage */ \
-    PSParallelCompact::mark_and_follow(cm, p))
+  assert(obj->is_array(), "obj must be array");
+  objArrayOop(obj)->follow_header(cm);
+  if (UseCompressedOops) {
+    objarray_follow_contents<narrowOop>(cm, obj, 0);
+  } else {
+    objarray_follow_contents<oop>(cm, obj, 0);
+  }
 }
 #endif // SERIALGC
 
--- a/src/share/vm/oops/objArrayKlass.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/oops/objArrayKlass.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -91,10 +91,18 @@
 
   // Garbage collection
   void oop_follow_contents(oop obj);
+  inline void oop_follow_contents(oop obj, int index);
+  template <class T> inline void objarray_follow_contents(oop obj, int index);
+
   int  oop_adjust_pointers(oop obj);
 
   // Parallel Scavenge and Parallel Old
   PARALLEL_GC_DECLS
+#ifndef SERIALGC
+  inline void oop_follow_contents(ParCompactionManager* cm, oop obj, int index);
+  template <class T> inline void
+    objarray_follow_contents(ParCompactionManager* cm, oop obj, int index);
+#endif // !SERIALGC
 
   // Iterators
   int oop_oop_iterate(oop obj, OopClosure* blk) {
@@ -131,5 +139,4 @@
   void oop_verify_on(oop obj, outputStream* st);
   void oop_verify_old_oop(oop obj, oop* p, bool allow_dirty);
   void oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty);
-
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/oops/objArrayKlass.inline.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+void objArrayKlass::oop_follow_contents(oop obj, int index) {
+  if (UseCompressedOops) {
+    objarray_follow_contents<narrowOop>(obj, index);
+  } else {
+    objarray_follow_contents<oop>(obj, index);
+  }
+}
+
+template <class T>
+void objArrayKlass::objarray_follow_contents(oop obj, int index) {
+  objArrayOop a = objArrayOop(obj);
+  const size_t len = size_t(a->length());
+  const size_t beg_index = size_t(index);
+  assert(beg_index < len || len == 0, "index too large");
+
+  const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
+  const size_t end_index = beg_index + stride;
+  T* const base = (T*)a->base();
+  T* const beg = base + beg_index;
+  T* const end = base + end_index;
+
+  // Push the non-NULL elements of the next stride on the marking stack.
+  for (T* e = beg; e < end; e++) {
+    MarkSweep::mark_and_push<T>(e);
+  }
+
+  if (end_index < len) {
+    MarkSweep::push_objarray(a, end_index); // Push the continuation.
+  }
+}
+
+#ifndef SERIALGC
+void objArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj,
+                                        int index) {
+  if (UseCompressedOops) {
+    objarray_follow_contents<narrowOop>(cm, obj, index);
+  } else {
+    objarray_follow_contents<oop>(cm, obj, index);
+  }
+}
+
+template <class T>
+void objArrayKlass::objarray_follow_contents(ParCompactionManager* cm, oop obj,
+                                             int index) {
+  objArrayOop a = objArrayOop(obj);
+  const size_t len = size_t(a->length());
+  const size_t beg_index = size_t(index);
+  assert(beg_index < len || len == 0, "index too large");
+
+  const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
+  const size_t end_index = beg_index + stride;
+  T* const base = (T*)a->base();
+  T* const beg = base + beg_index;
+  T* const end = base + end_index;
+
+  // Push the non-NULL elements of the next stride on the marking stack.
+  for (T* e = beg; e < end; e++) {
+    PSParallelCompact::mark_and_push<T>(cm, e);
+  }
+
+  if (end_index < len) {
+    cm->push_objarray(a, end_index); // Push the continuation.
+  }
+}
+#endif // #ifndef SERIALGC
--- a/src/share/vm/oops/typeArrayKlass.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/oops/typeArrayKlass.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -123,16 +123,16 @@
      || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
   }
+  // Check zero copy
+  if (length == 0)
+    return;
 
   // This is an attempt to make the copy_array fast.
-  // NB: memmove takes care of overlapping memory segments.
-  // Potential problem: memmove is not guaranteed to be word atomic
-  // Revisit in Merlin
   int l2es = log2_element_size();
   int ihs = array_header_in_bytes() / wordSize;
-  char* src = (char*) ((oop*)s + ihs) + (src_pos << l2es);
-  char* dst = (char*) ((oop*)d + ihs) + (dst_pos << l2es);
-  memmove(dst, src, length << l2es);
+  char* src = (char*) ((oop*)s + ihs) + ((size_t)src_pos << l2es);
+  char* dst = (char*) ((oop*)d + ihs) + ((size_t)dst_pos << l2es);
+  Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es);
 }
 
 
--- a/src/share/vm/opto/cfgnode.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/cfgnode.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -956,6 +956,7 @@
     }
     if( jtkp && ttkp ) {
       if( jtkp->is_loaded() &&  jtkp->klass()->is_interface() &&
+          !jtkp->klass_is_exact() && // Keep exact interface klass (6894807)
           ttkp->is_loaded() && !ttkp->klass()->is_interface() ) {
         assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) ||
                ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), "");
--- a/src/share/vm/opto/loopTransform.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/loopTransform.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc.  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
@@ -1785,6 +1785,8 @@
 bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, bool must_reason_predicate) {
   Node *in0 = proj->in(0);
   if (!in0->is_If()) return false;
+  // Variation of a dead If node.
+  if (in0->outcnt() < 2)  return false;
   IfNode* iff = in0->as_If();
 
   // we need "If(Conv2B(Opaque1(...)))" pattern for must_reason_predicate
@@ -2086,29 +2088,41 @@
 BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl,
                                        int scale, Node* offset,
                                        Node* init, Node* limit, Node* stride,
-                                       Node* range) {
+                                       Node* range, bool upper) {
+  DEBUG_ONLY(ttyLocker ttyl);
+  if (TraceLoopPredicate) tty->print("rc_predicate ");
+
   Node* max_idx_expr  = init;
   int stride_con = stride->get_int();
-  if ((stride_con > 0) == (scale > 0)) {
+  if ((stride_con > 0) == (scale > 0) == upper) {
     max_idx_expr = new (C, 3) SubINode(limit, stride);
     register_new_node(max_idx_expr, ctrl);
+    if (TraceLoopPredicate) tty->print("(limit - stride) ");
+  } else {
+    if (TraceLoopPredicate) tty->print("init ");
   }
 
   if (scale != 1) {
     ConNode* con_scale = _igvn.intcon(scale);
     max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale);
     register_new_node(max_idx_expr, ctrl);
+    if (TraceLoopPredicate) tty->print("* %d ", scale);
   }
 
   if (offset && (!offset->is_Con() || offset->get_int() != 0)){
     max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset);
     register_new_node(max_idx_expr, ctrl);
+    if (TraceLoopPredicate)
+      if (offset->is_Con()) tty->print("+ %d ", offset->get_int());
+      else tty->print("+ offset ");
   }
 
   CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range);
   register_new_node(cmp, ctrl);
   BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt);
   register_new_node(bol, ctrl);
+
+  if (TraceLoopPredicate) tty->print_cr("<u range");
   return bol;
 }
 
@@ -2117,6 +2131,18 @@
 bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
   if (!UseLoopPredicate) return false;
 
+  if (!loop->_head->is_Loop()) {
+    // Could be a simple region when irreducible loops are present.
+    return false;
+  }
+
+  CountedLoopNode *cl = NULL;
+  if (loop->_head->is_CountedLoop()) {
+    cl = loop->_head->as_CountedLoop();
+    // do nothing for iteration-splitted loops
+    if (!cl->is_normal_loop()) return false;
+  }
+
   // Too many traps seen?
   bool tmt = C->too_many_traps(C->method(), 0, Deoptimization::Reason_predicate);
   int tc = C->trap_count(Deoptimization::Reason_predicate);
@@ -2129,13 +2155,6 @@
     return false;
   }
 
-  CountedLoopNode *cl = NULL;
-  if (loop->_head->is_CountedLoop()) {
-    cl = loop->_head->as_CountedLoop();
-    // do nothing for iteration-splitted loops
-    if(!cl->is_normal_loop()) return false;
-  }
-
   LoopNode *lpn  = loop->_head->as_Loop();
   Node* entry = lpn->in(LoopNode::EntryControl);
 
@@ -2180,7 +2199,6 @@
   while (if_proj_list.size() > 0) {
     // Following are changed to nonnull when a predicate can be hoisted
     ProjNode* new_predicate_proj = NULL;
-    BoolNode* new_predicate_bol   = NULL;
 
     ProjNode* proj = if_proj_list.pop()->as_Proj();
     IfNode*   iff  = proj->in(0)->as_If();
@@ -2211,93 +2229,120 @@
       // Invariant test
       new_predicate_proj = create_new_if_for_predicate(predicate_proj);
       Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
-      new_predicate_bol  = invar.clone(bol, ctrl)->as_Bool();
-      if (TraceLoopPredicate) tty->print("invariant");
+      BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
+
+      // Negate test if necessary
+      bool negated = false;
+      if (proj->_con != predicate_proj->_con) {
+        new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
+        register_new_node(new_predicate_bol, ctrl);
+        negated = true;
+      }
+      IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
+      _igvn.hash_delete(new_predicate_iff);
+      new_predicate_iff->set_req(1, new_predicate_bol);
+      if (TraceLoopPredicate) tty->print_cr("invariant if%s: %d", negated ? " negated" : "", new_predicate_iff->_idx);
+
     } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) {
-      // Range check (only for counted loops)
-      new_predicate_proj = create_new_if_for_predicate(predicate_proj);
-      Node *ctrl = new_predicate_proj->in(0)->as_If()->in(0);
+      assert(proj->_con == predicate_proj->_con, "must match");
+
+      // Range check for counted loops
       const Node*    cmp    = bol->in(1)->as_Cmp();
       Node*          idx    = cmp->in(1);
       assert(!invar.is_invariant(idx), "index is variant");
       assert(cmp->in(2)->Opcode() == Op_LoadRange, "must be");
-      LoadRangeNode* ld_rng = (LoadRangeNode*)cmp->in(2); // LoadRangeNode
+      Node* ld_rng = cmp->in(2); // LoadRangeNode
       assert(invar.is_invariant(ld_rng), "load range must be invariant");
-      ld_rng = (LoadRangeNode*)invar.clone(ld_rng, ctrl);
       int scale    = 1;
       Node* offset = zero;
       bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset);
       assert(ok, "must be index expression");
+
+      Node* init    = cl->init_trip();
+      Node* limit   = cl->limit();
+      Node* stride  = cl->stride();
+
+      // Build if's for the upper and lower bound tests.  The
+      // lower_bound test will dominate the upper bound test and all
+      // cloned or created nodes will use the lower bound test as
+      // their declared control.
+      ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj);
+      ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj);
+      assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
+      Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
+
+      // Perform cloning to keep Invariance state correct since the
+      // late schedule will place invariant things in the loop.
+      ld_rng = invar.clone(ld_rng, ctrl);
       if (offset && offset != zero) {
         assert(invar.is_invariant(offset), "offset must be loop invariant");
         offset = invar.clone(offset, ctrl);
       }
-      Node* init    = cl->init_trip();
-      Node* limit   = cl->limit();
-      Node* stride  = cl->stride();
-      new_predicate_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng);
-      if (TraceLoopPredicate) tty->print("range check");
-    }
 
-    if (new_predicate_proj == NULL) {
+      // Test the lower bound
+      Node*  lower_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, false);
+      IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
+      _igvn.hash_delete(lower_bound_iff);
+      lower_bound_iff->set_req(1, lower_bound_bol);
+      if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
+
+      // Test the upper bound
+      Node* upper_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, true);
+      IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
+      _igvn.hash_delete(upper_bound_iff);
+      upper_bound_iff->set_req(1, upper_bound_bol);
+      if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx);
+
+      // Fall through into rest of the clean up code which will move
+      // any dependent nodes onto the upper bound test.
+      new_predicate_proj = upper_bound_proj;
+    } else {
       // The other proj of the "iff" is a uncommon trap projection, and we can assume
       // the other proj will not be executed ("executed" means uct raised).
       continue;
-    } else {
-      // Success - attach condition (new_predicate_bol) to predicate if
-      invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
-      IfNode* new_iff = new_predicate_proj->in(0)->as_If();
+    }
 
-      // Negate test if necessary
-      if (proj->_con != predicate_proj->_con) {
-        new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
-        register_new_node(new_predicate_bol, new_iff->in(0));
-        if (TraceLoopPredicate) tty->print_cr(" if negated: %d", iff->_idx);
-      } else {
-        if (TraceLoopPredicate) tty->print_cr(" if: %d", iff->_idx);
+    // Success - attach condition (new_predicate_bol) to predicate if
+    invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
+
+    // Eliminate the old if in the loop body
+    _igvn.hash_delete(iff);
+    iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true);
+
+    Node* ctrl = new_predicate_proj; // new control
+    ProjNode* dp = proj;     // old control
+    assert(get_loop(dp) == loop, "guaranteed at the time of collecting proj");
+    // Find nodes (depends only on the test) off the surviving projection;
+    // move them outside the loop with the control of proj_clone
+    for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
+      Node* cd = dp->fast_out(i); // Control-dependent node
+      if (cd->depends_only_on_test()) {
+        assert(cd->in(0) == dp, "");
+        _igvn.hash_delete(cd);
+        cd->set_req(0, ctrl); // ctrl, not NULL
+        set_early_ctrl(cd);
+        _igvn._worklist.push(cd);
+        IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
+        if (new_loop != loop) {
+          if (!loop->_child) loop->_body.yank(cd);
+          if (!new_loop->_child ) new_loop->_body.push(cd);
+        }
+        --i;
+        --imax;
       }
+    }
 
-      _igvn.hash_delete(new_iff);
-      new_iff->set_req(1, new_predicate_bol);
-
-      _igvn.hash_delete(iff);
-      iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true);
-
-      Node* ctrl = new_predicate_proj; // new control
-      ProjNode* dp = proj;     // old control
-      assert(get_loop(dp) == loop, "guarenteed at the time of collecting proj");
-      // Find nodes (depends only on the test) off the surviving projection;
-      // move them outside the loop with the control of proj_clone
-      for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
-        Node* cd = dp->fast_out(i); // Control-dependent node
-        if (cd->depends_only_on_test()) {
-          assert(cd->in(0) == dp, "");
-          _igvn.hash_delete(cd);
-          cd->set_req(0, ctrl); // ctrl, not NULL
-          set_early_ctrl(cd);
-          _igvn._worklist.push(cd);
-          IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
-          if (new_loop != loop) {
-            if (!loop->_child) loop->_body.yank(cd);
-            if (!new_loop->_child ) new_loop->_body.push(cd);
-          }
-          --i;
-          --imax;
-        }
-      }
-
-      hoisted = true;
-      C->set_major_progress();
-    }
+    hoisted = true;
+    C->set_major_progress();
   } // end while
 
 #ifndef PRODUCT
-    // report that the loop predication has been actually performed
-    // for this loop
-    if (TraceLoopPredicate && hoisted) {
-      tty->print("Loop Predication Performed:");
-      loop->dump_head();
-    }
+  // report that the loop predication has been actually performed
+  // for this loop
+  if (TraceLoopPredicate && hoisted) {
+    tty->print("Loop Predication Performed:");
+    loop->dump_head();
+  }
 #endif
 
   return hoisted;
--- a/src/share/vm/opto/loopnode.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/loopnode.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -821,7 +821,7 @@
   BoolNode* rc_predicate(Node* ctrl,
                          int scale, Node* offset,
                          Node* init, Node* limit, Node* stride,
-                         Node* range);
+                         Node* range, bool upper);
 
   // Implementation of the loop predication to promote checks outside the loop
   bool loop_predication_impl(IdealLoopTree *loop);
--- a/src/share/vm/opto/matcher.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/matcher.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -373,8 +373,8 @@
   // to implement the UseStrictFP mode.
   static const bool strict_fp_requires_explicit_rounding;
 
-  // Do floats take an entire double register or just half?
-  static const bool float_in_double;
+  // Are floats conerted to double when stored to stack during deoptimization?
+  static bool float_in_double();
   // Do ints take an entire long register or just half?
   static const bool int_in_long;
 
--- a/src/share/vm/opto/output.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/output.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -678,7 +678,7 @@
 #endif //_LP64
     else if( (t->base() == Type::FloatBot || t->base() == Type::FloatCon) &&
                OptoReg::is_reg(regnum) ) {
-      array->append(new_loc_value( _regalloc, regnum, Matcher::float_in_double
+      array->append(new_loc_value( _regalloc, regnum, Matcher::float_in_double()
                                    ? Location::float_in_dbl : Location::normal ));
     } else if( t->base() == Type::Int && OptoReg::is_reg(regnum) ) {
       array->append(new_loc_value( _regalloc, regnum, Matcher::int_in_long
--- a/src/share/vm/opto/parse1.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/parse1.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -237,7 +237,6 @@
     C->record_method_not_compilable("OSR in empty or breakpointed method");
     return;
   }
-  MethodLivenessResult raw_live_locals = method()->raw_liveness_at_bci(osr_bci());
 
   // Extract the needed locals from the interpreter frame.
   Node *locals_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals-1)*wordSize);
@@ -306,6 +305,7 @@
   SafePointNode* bad_type_exit = clone_map();
   bad_type_exit->set_control(new (C, 1) RegionNode(1));
 
+  assert(osr_block->flow()->jsrs()->size() == 0, "should be no jsrs live at osr point");
   for (index = 0; index < max_locals; index++) {
     if (stopped())  break;
     Node* l = local(index);
@@ -317,8 +317,18 @@
         continue;
       }
     }
-    if (type->basic_type() == T_ADDRESS && !raw_live_locals.at(index)) {
-      // Skip type check for dead address locals
+    if (osr_block->flow()->local_type_at(index)->is_return_address()) {
+      // In our current system it's illegal for jsr addresses to be
+      // live into an OSR entry point because the compiler performs
+      // inlining of jsrs.  ciTypeFlow has a bailout that detect this
+      // case and aborts the compile if addresses are live into an OSR
+      // entry point.  Because of that we can assume that any address
+      // locals at the OSR entry point are dead.  Method liveness
+      // isn't precise enought to figure out that they are dead in all
+      // cases so simply skip checking address locals all
+      // together. Any type check is guaranteed to fail since the
+      // interpreter type is the result of a load which might have any
+      // value and the expected type is a constant.
       continue;
     }
     set_local(index, check_interpreter_type(l, type, bad_type_exit));
--- a/src/share/vm/opto/runtime.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/runtime.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -864,7 +864,7 @@
     thread->set_exception_handler_pc(handler_address);
     thread->set_exception_stack_size(0);
 
-    // Check if the exception PC is a MethodHandle call.
+    // Check if the exception PC is a MethodHandle call site.
     thread->set_is_method_handle_exception(nm->is_method_handle_return(pc));
   }
 
@@ -952,7 +952,7 @@
 
   thread->set_vm_result(exception);
   // Frame not compiled (handles deoptimization blob)
-  return SharedRuntime::raw_exception_handler_for_return_address(ret_pc);
+  return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc);
 }
 
 
--- a/src/share/vm/opto/split_if.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/split_if.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2010 Sun Microsystems, Inc.  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
@@ -187,10 +187,20 @@
   }
 #endif
 
+  // ConvI2L may have type information on it which becomes invalid if
+  // it moves up in the graph so change any clones so widen the type
+  // to TypeLong::INT when pushing it up.
+  const Type* rtype = NULL;
+  if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::INT) {
+    rtype = TypeLong::INT;
+  }
+
   // Now actually split-up this guy.  One copy per control path merging.
   Node *phi = PhiNode::make_blank(blk1, n);
   for( uint j = 1; j < blk1->req(); j++ ) {
     Node *x = n->clone();
+    // Widen the type of the ConvI2L when pushing up.
+    if (rtype != NULL) x->as_Type()->set_type(rtype);
     if( n->in(0) && n->in(0) == blk1 )
       x->set_req( 0, blk1->in(j) );
     for( uint i = 1; i < n->req(); i++ ) {
--- a/src/share/vm/opto/type.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/opto/type.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -2545,12 +2545,15 @@
       ftip->is_loaded() &&  ftip->klass()->is_interface() &&
       ktip->is_loaded() && !ktip->klass()->is_interface()) {
     // Happens in a CTW of rt.jar, 320-341, no extra flags
+    assert(!ftip->klass_is_exact(), "interface could not be exact");
     return ktip->cast_to_ptr_type(ftip->ptr());
   }
+  // Interface klass type could be exact in opposite to interface type,
+  // return it here instead of incorrect Constant ptr J/L/Object (6894807).
   if (ftkp != NULL && ktkp != NULL &&
       ftkp->is_loaded() &&  ftkp->klass()->is_interface() &&
+      !ftkp->klass_is_exact() && // Keep exact interface klass
       ktkp->is_loaded() && !ktkp->klass()->is_interface()) {
-    // Happens in a CTW of rt.jar, 320-341, no extra flags
     return ktkp->cast_to_ptr_type(ftkp->ptr());
   }
 
@@ -2809,7 +2812,8 @@
         // then we can subclass in the Java class hierarchy.
         if (klass()->equals(ciEnv::current()->Object_klass())) {
           // that is, tp's array type is a subtype of my klass
-          return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
+          return TypeAryPtr::make(ptr, (ptr == Constant ? tp->const_oop() : NULL),
+                                  tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
         }
       }
       // The other case cannot happen, since I cannot be a subtype of an array.
@@ -3415,7 +3419,8 @@
         // then we can subclass in the Java class hierarchy.
         if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
           // that is, my array type is a subtype of 'tp' klass
-          return make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
+          return make( ptr, (ptr == Constant ? const_oop() : NULL),
+                       _ary, _klass, _klass_is_exact, offset, instance_id );
         }
       }
       // The other case cannot happen, since t cannot be a subtype of an array.
--- a/src/share/vm/prims/jni.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/prims/jni.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -3401,12 +3401,16 @@
   thread->set_thread_state(_thread_in_vm);
   // Must do this before initialize_thread_local_storage
   thread->record_stack_base_and_size();
+
   thread->initialize_thread_local_storage();
 
   if (!os::create_attached_thread(thread)) {
     delete thread;
     return JNI_ERR;
   }
+  // Enable stack overflow checks
+  thread->create_stack_guard_pages();
+
   thread->initialize_tlab();
 
   // Crucial that we do not have a safepoint check for this thread, since it has
@@ -3452,9 +3456,6 @@
   // to regrab the threads_lock
   thread->set_attached();
 
-  // Enable stack overflow checks
-  thread->create_stack_guard_pages();
-
   // Set java thread status.
   java_lang_Thread::set_thread_status(thread->threadObj(),
               java_lang_Thread::RUNNABLE);
--- a/src/share/vm/prims/jvm.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/prims/jvm.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -26,6 +26,10 @@
 #include "incls/_jvm.cpp.incl"
 #include <errno.h>
 
+HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__end, int);
+HS_DTRACE_PROBE_DECL0(hotspot, thread__yield);
+
 /*
   NOTE about use of any ctor or function call that can trigger a safepoint/GC:
   such ctors and calls MUST NOT come between an oop declaration/init and its
@@ -2762,6 +2766,7 @@
 JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))
   JVMWrapper("JVM_Yield");
   if (os::dont_yield()) return;
+  HS_DTRACE_PROBE0(hotspot, thread__yield);
   // When ConvertYieldToSleep is off (default), this matches the classic VM use of yield.
   // Critical for similar threading behaviour
   if (ConvertYieldToSleep) {
@@ -2787,6 +2792,8 @@
   // And set new thread state to SLEEPING.
   JavaThreadSleepState jtss(thread);
 
+  HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis);
+
   if (millis == 0) {
     // When ConvertSleepToYield is on, this matches the classic VM implementation of
     // JVM_Sleep. Critical for similar threading behaviour (Win32)
@@ -2807,6 +2814,7 @@
       // An asynchronous exception (e.g., ThreadDeathException) could have been thrown on
       // us while we were sleeping. We do not overwrite those.
       if (!HAS_PENDING_EXCEPTION) {
+        HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);
         // TODO-FIXME: THROW_MSG returns which means we will not call set_state()
         // to properly restore the thread state.  That's likely wrong.
         THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
@@ -2814,6 +2822,7 @@
     }
     thread->osthread()->set_state(old_state);
   }
+  HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);
 JVM_END
 
 JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
--- a/src/share/vm/prims/methodHandles.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/prims/methodHandles.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2010 Sun Microsystems, Inc.  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
@@ -82,6 +82,10 @@
   NULL
 };
 
+// Adapters.
+MethodHandlesAdapterBlob* MethodHandles::_adapter_code      = NULL;
+int                       MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size;
+
 jobject MethodHandles::_raise_exception_method;
 
 #ifdef ASSERT
@@ -95,6 +99,41 @@
 }
 #endif
 
+
+//------------------------------------------------------------------------------
+// MethodHandles::generate_adapters
+//
+void MethodHandles::generate_adapters() {
+  if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL)  return;
+
+  assert(_adapter_code == NULL, "generate only once");
+
+  ResourceMark rm;
+  TraceTime timer("MethodHandles adapters generation", TraceStartupTime);
+  _adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size);
+  if (_adapter_code == NULL)
+    vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
+  CodeBuffer code(_adapter_code->instructions_begin(), _adapter_code->instructions_size());
+
+  MethodHandlesAdapterGenerator g(&code);
+  g.generate();
+}
+
+
+//------------------------------------------------------------------------------
+// MethodHandlesAdapterGenerator::generate
+//
+void MethodHandlesAdapterGenerator::generate() {
+  // Generate generic method handle adapters.
+  for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
+       ek < MethodHandles::_EK_LIMIT;
+       ek = MethodHandles::EntryKind(1 + (int)ek)) {
+    StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
+    MethodHandles::generate_method_handle_stub(_masm, ek);
+  }
+}
+
+
 void MethodHandles::set_enabled(bool z) {
   if (_enabled != z) {
     guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
--- a/src/share/vm/prims/methodHandles.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/prims/methodHandles.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2008-2010 Sun Microsystems, Inc.  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
@@ -115,6 +115,10 @@
   static const char*        _entry_names[_EK_LIMIT+1];
   static jobject            _raise_exception_method;
 
+  // Adapters.
+  static MethodHandlesAdapterBlob* _adapter_code;
+  static int                       _adapter_code_size;
+
   static bool ek_valid(EntryKind ek)            { return (uint)ek < (uint)_EK_LIMIT; }
   static bool conv_op_valid(int op)             { return (uint)op < (uint)CONV_OP_LIMIT; }
 
@@ -133,6 +137,43 @@
     _entries[ek] = me;
   }
 
+  // Some adapter helper functions.
+  static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) {
+    switch (ek) {
+    case _bound_int_mh        : // fall-thru
+    case _bound_int_direct_mh : arg_type = T_INT;    arg_mask = _INSERT_INT_MASK;  break;
+    case _bound_long_mh       : // fall-thru
+    case _bound_long_direct_mh: arg_type = T_LONG;   arg_mask = _INSERT_LONG_MASK; break;
+    case _bound_ref_mh        : // fall-thru
+    case _bound_ref_direct_mh : arg_type = T_OBJECT; arg_mask = _INSERT_REF_MASK;  break;
+    default: ShouldNotReachHere();
+    }
+    arg_slots = type2size[arg_type];
+  }
+
+  static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) {
+    int swap_slots = 0;
+    switch (ek) {
+    case _adapter_opt_swap_1:     swap_slots = 1; rotate =  0; break;
+    case _adapter_opt_swap_2:     swap_slots = 2; rotate =  0; break;
+    case _adapter_opt_rot_1_up:   swap_slots = 1; rotate =  1; break;
+    case _adapter_opt_rot_1_down: swap_slots = 1; rotate = -1; break;
+    case _adapter_opt_rot_2_up:   swap_slots = 2; rotate =  1; break;
+    case _adapter_opt_rot_2_down: swap_slots = 2; rotate = -1; break;
+    default: ShouldNotReachHere();
+    }
+    // Return the size of the stack slots to move in bytes.
+    swap_bytes = swap_slots * Interpreter::stackElementSize();
+  }
+
+  static int get_ek_adapter_opt_spread_info(EntryKind ek) {
+    switch (ek) {
+    case _adapter_opt_spread_0: return  0;
+    case _adapter_opt_spread_1: return  1;
+    default                   : return -1;
+    }
+  }
+
   static methodOop raise_exception_method() {
     oop rem = JNIHandles::resolve(_raise_exception_method);
     assert(rem == NULL || rem->is_method(), "");
@@ -230,7 +271,10 @@
   // bit values for suppress argument to expand_MemberName:
   enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
 
-  // called from InterpreterGenerator and StubGenerator
+  // Generate MethodHandles adapters.
+  static void generate_adapters();
+
+  // Called from InterpreterGenerator and MethodHandlesAdapterGenerator.
   static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
   static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
 
@@ -385,13 +429,13 @@
   static void insert_arg_slots(MacroAssembler* _masm,
                                RegisterOrConstant arg_slots,
                                int arg_mask,
-                               Register rax_argslot,
-                               Register rbx_temp, Register rdx_temp);
+                               Register argslot_reg,
+                               Register temp_reg, Register temp2_reg);
 
   static void remove_arg_slots(MacroAssembler* _masm,
                                RegisterOrConstant arg_slots,
-                               Register rax_argslot,
-                               Register rbx_temp, Register rdx_temp);
+                               Register argslot_reg,
+                               Register temp_reg, Register temp2_reg);
 };
 
 
@@ -447,3 +491,14 @@
 
 address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); }
 address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); }
+
+
+//------------------------------------------------------------------------------
+// MethodHandlesAdapterGenerator
+//
+class MethodHandlesAdapterGenerator : public StubCodeGenerator {
+public:
+  MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code) {}
+
+  void generate();
+};
--- a/src/share/vm/prims/unsafe.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/prims/unsafe.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -29,6 +29,10 @@
 #include "incls/_precompiled.incl"
 #include "incls/_unsafe.cpp.incl"
 
+HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t);
+HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t);
+
 #define MAX_OBJECT_SIZE \
   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
     + ((julong)max_jint * sizeof(double)) )
@@ -1083,8 +1087,10 @@
 
 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
   UnsafeWrapper("Unsafe_Park");
+  HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
   JavaThreadParkedState jtps(thread, time != 0);
   thread->parker()->park(isAbsolute != 0, time);
+  HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
 UNSAFE_END
 
 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
@@ -1116,6 +1122,7 @@
     }
   }
   if (p != NULL) {
+    HS_DTRACE_PROBE1(hotspot, thread__unpark, p);
     p->unpark();
   }
 UNSAFE_END
--- a/src/share/vm/runtime/arguments.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1203,6 +1203,11 @@
   if (!FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim) || !FLAG_IS_DEFAULT(OldPLABWeight)) {
     CFLS_LAB::modify_initialization(OldPLABSize, OldPLABWeight);
   }
+  if (PrintGCDetails && Verbose) {
+    tty->print_cr("MarkStackSize: %uk  MarkStackSizeMax: %uk",
+      MarkStackSize / K, MarkStackSizeMax / K);
+    tty->print_cr("ConcGCThreads: %u", ConcGCThreads);
+  }
 }
 #endif // KERNEL
 
@@ -1339,6 +1344,15 @@
   if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
     FLAG_SET_DEFAULT(MaxGCPauseMillis, 200);
   }
+
+  if (FLAG_IS_DEFAULT(MarkStackSize)) {
+    FLAG_SET_DEFAULT(MarkStackSize, 128 * TASKQUEUE_SIZE);
+  }
+  if (PrintGCDetails && Verbose) {
+    tty->print_cr("MarkStackSize: %uk  MarkStackSizeMax: %uk",
+      MarkStackSize / K, MarkStackSizeMax / K);
+    tty->print_cr("ConcGCThreads: %u", ConcGCThreads);
+  }
 }
 
 void Arguments::set_heap_size() {
@@ -1737,6 +1751,11 @@
     status = false;
   }
 
+  if (UseG1GC) {
+    status = status && verify_percentage(InitiatingHeapOccupancyPercent,
+                                         "InitiatingHeapOccupancyPercent");
+  }
+
   status = status && verify_interval(RefDiscoveryPolicy,
                                      ReferenceProcessor::DiscoveryPolicyMin,
                                      ReferenceProcessor::DiscoveryPolicyMax,
@@ -1795,6 +1814,29 @@
   return false;
 }
 
+bool Arguments::parse_uintx(const char* value,
+                            uintx* uintx_arg,
+                            uintx min_size) {
+
+  // Check the sign first since atomull() parses only unsigned values.
+  bool value_is_positive = !(*value == '-');
+
+  if (value_is_positive) {
+    julong n;
+    bool good_return = atomull(value, &n);
+    if (good_return) {
+      bool above_minimum = n >= min_size;
+      bool value_is_too_large = n > max_uintx;
+
+      if (above_minimum && !value_is_too_large) {
+        *uintx_arg = n;
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
                                                   julong* long_arg,
                                                   julong min_size) {
@@ -2453,6 +2495,37 @@
       jio_fprintf(defaultStream::error_stream(),
                   "Please use -XX:YoungPLABSize in place of "
                   "-XX:ParallelGCToSpaceAllocBufferSize in the future\n");
+    } else if (match_option(option, "-XX:CMSMarkStackSize=", &tail) ||
+               match_option(option, "-XX:G1MarkStackSize=", &tail)) {
+      julong stack_size = 0;
+      ArgsRange errcode = parse_memory_size(tail, &stack_size, 1);
+      if (errcode != arg_in_range) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "Invalid mark stack size: %s\n", option->optionString);
+        describe_range_error(errcode);
+        return JNI_EINVAL;
+      }
+      FLAG_SET_CMDLINE(uintx, MarkStackSize, stack_size);
+    } else if (match_option(option, "-XX:CMSMarkStackSizeMax=", &tail)) {
+      julong max_stack_size = 0;
+      ArgsRange errcode = parse_memory_size(tail, &max_stack_size, 1);
+      if (errcode != arg_in_range) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "Invalid maximum mark stack size: %s\n",
+                    option->optionString);
+        describe_range_error(errcode);
+        return JNI_EINVAL;
+      }
+      FLAG_SET_CMDLINE(uintx, MarkStackSizeMax, max_stack_size);
+    } else if (match_option(option, "-XX:ParallelMarkingThreads=", &tail) ||
+               match_option(option, "-XX:ParallelCMSThreads=", &tail)) {
+      uintx conc_threads = 0;
+      if (!parse_uintx(tail, &conc_threads, 1)) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "Invalid concurrent threads: %s\n", option->optionString);
+        return JNI_EINVAL;
+      }
+      FLAG_SET_CMDLINE(uintx, ConcGCThreads, conc_threads);
     } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
       // Skip -XX:Flags= since that case has already been handled
       if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
@@ -2784,6 +2857,12 @@
   }
 #endif // _LP64
 
+  // MethodHandles code does not support TaggedStackInterpreter.
+  if (EnableMethodHandles && TaggedStackInterpreter) {
+    warning("TaggedStackInterpreter is not supported by MethodHandles code.  Disabling TaggedStackInterpreter.");
+    TaggedStackInterpreter = false;
+  }
+
   // Check the GC selections again.
   if (!check_gc_consistency()) {
     return JNI_EINVAL;
--- a/src/share/vm/runtime/arguments.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/arguments.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -343,6 +343,12 @@
   static ArgsRange check_memory_size(julong size, julong min_size);
   static ArgsRange parse_memory_size(const char* s, julong* long_arg,
                                      julong min_size);
+  // Parse a string for a unsigned integer.  Returns true if value
+  // is an unsigned integer greater than or equal to the minimum
+  // parameter passed and returns the value in uintx_arg.  Returns
+  // false otherwise, with uintx_arg undefined.
+  static bool parse_uintx(const char* value, uintx* uintx_arg,
+                          uintx min_size);
 
   // methods to build strings from individual args
   static void build_jvm_args(const char* arg);
--- a/src/share/vm/runtime/globals.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/globals.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1245,9 +1245,6 @@
   product(uintx, ParallelGCThreads, 0,                                      \
           "Number of parallel threads parallel gc will use")                \
                                                                             \
-  product(uintx, ParallelCMSThreads, 0,                                     \
-          "Max number of threads CMS will use for concurrent work")         \
-                                                                            \
   develop(bool, ParallelOldGCSplitALot, false,                              \
           "Provoke splitting (copying data from a young gen space to"       \
           "multiple destination spaces)")                                   \
@@ -1258,8 +1255,8 @@
   develop(bool, TraceRegionTasksQueuing, false,                             \
           "Trace the queuing of the region tasks")                          \
                                                                             \
-  product(uintx, ParallelMarkingThreads, 0,                                 \
-          "Number of marking threads concurrent gc will use")               \
+  product(uintx, ConcGCThreads, 0,                                          \
+          "Number of threads concurrent gc will use")                       \
                                                                             \
   product(uintx, YoungPLABSize, 4096,                                       \
           "Size of young gen promotion labs (in HeapWords)")                \
@@ -1535,11 +1532,11 @@
   develop(bool, CMSOverflowEarlyRestoration, false,                         \
           "Whether preserved marks should be restored early")               \
                                                                             \
-  product(uintx, CMSMarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M),           \
-          "Size of CMS marking stack")                                      \
-                                                                            \
-  product(uintx, CMSMarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M),       \
-          "Max size of CMS marking stack")                                  \
+  product(uintx, MarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M),              \
+          "Size of marking stack")                                          \
+                                                                            \
+  product(uintx, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M),          \
+          "Max size of marking stack")                                      \
                                                                             \
   notproduct(bool, CMSMarkStackOverflowALot, false,                         \
           "Whether we should simulate frequent marking stack / work queue"  \
@@ -1724,6 +1721,13 @@
           "Percentage CMS generation occupancy to start a CMS collection "  \
           "cycle. A negative value means that CMSTriggerRatio is used")     \
                                                                             \
+  product(uintx, InitiatingHeapOccupancyPercent, 45,                        \
+          "Percentage of the (entire) heap occupancy to start a "           \
+          "concurrent GC cycle. It us used by GCs that trigger a "          \
+          "concurrent GC cycle based on the occupancy of the entire heap, " \
+          "not just one of the generations (e.g., G1). A value of 0 "       \
+          "denotes 'do constant GC cycles'.")                               \
+                                                                            \
   product(intx, CMSInitiatingPermOccupancyFraction, -1,                     \
           "Percentage CMS perm generation occupancy to start a "            \
           "CMScollection cycle. A negative value means that "               \
@@ -1791,6 +1795,10 @@
   product(uintx, PreserveMarkStackSize, 1024,                               \
           "Size for stack used in promotion failure handling")              \
                                                                             \
+  develop(uintx, ObjArrayMarkingStride, 512,                                \
+          "Number of ObjArray elements to push onto the marking stack"      \
+          "before pushing a continuation entry")                            \
+                                                                            \
   product_pd(bool, UseTLAB, "Use thread-local object allocation")           \
                                                                             \
   product_pd(bool, ResizeTLAB,                                              \
@@ -2285,6 +2293,10 @@
           "print safepoint statistics only when safepoint takes"            \
           " more than PrintSafepointSatisticsTimeout in millis")            \
                                                                             \
+  product(bool, TraceSafepointCleanupTime, false,                           \
+          "print the break down of clean up tasks performed during"         \
+          " safepoint")                                                     \
+                                                                            \
   develop(bool, InlineAccessors, true,                                      \
           "inline accessor methods (get/set)")                              \
                                                                             \
@@ -2925,7 +2937,7 @@
   product(uintx, OldSize, ScaleForWordSize(4*M),                            \
           "Initial tenured generation size (in bytes)")                     \
                                                                             \
-  product(uintx, NewSize, ScaleForWordSize(4*M),                            \
+  product(uintx, NewSize, ScaleForWordSize(1*M),                            \
           "Initial new generation size (in bytes)")                         \
                                                                             \
   product(uintx, MaxNewSize, max_uintx,                                     \
--- a/src/share/vm/runtime/init.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/init.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc.  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
@@ -118,6 +118,9 @@
   javaClasses_init();  // must happen after vtable initialization
   stubRoutines_init2(); // note: StubRoutines need 2-phase init
 
+  // Generate MethodHandles adapters.
+  MethodHandles::generate_adapters();
+
   // Although we'd like to, we can't easily do a heap verify
   // here because the main thread isn't yet a JavaThread, so
   // its TLAB may not be made parseable from the usual interfaces.
--- a/src/share/vm/runtime/os.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/os.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -218,6 +218,9 @@
 
   static bool   guard_memory(char* addr, size_t bytes);
   static bool   unguard_memory(char* addr, size_t bytes);
+  static bool   create_stack_guard_pages(char* addr, size_t bytes);
+  static bool   remove_stack_guard_pages(char* addr, size_t bytes);
+
   static char*  map_memory(int fd, const char* file_name, size_t file_offset,
                            char *addr, size_t bytes, bool read_only = false,
                            bool allow_exec = false);
--- a/src/share/vm/runtime/safepoint.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/safepoint.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -30,8 +30,8 @@
 
 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
 volatile int  SafepointSynchronize::_waiting_to_block = 0;
-jlong SafepointSynchronize::_last_safepoint = 0;
 volatile int SafepointSynchronize::_safepoint_counter = 0;
+long  SafepointSynchronize::_end_of_last_safepoint = 0;
 static volatile int PageArmed = 0 ;        // safepoint polling page is RO|RW vs PROT_NONE
 static volatile int TryingToBlock = 0 ;    // proximate value -- for advisory use only
 static bool timeout_error_printed = false;
@@ -42,7 +42,10 @@
   Thread* myThread = Thread::current();
   assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
 
-  _last_safepoint = os::javaTimeNanos();
+  if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
+    _safepoint_begin_time = os::javaTimeNanos();
+    _ts_of_current_safepoint = tty->time_stamp().seconds();
+  }
 
 #ifndef SERIALGC
   if (UseConcMarkSweepGC) {
@@ -320,6 +323,11 @@
 
   // Call stuff that needs to be run when a safepoint is just about to be completed
   do_cleanup_tasks();
+
+  if (PrintSafepointStatistics) {
+    // Record how much time spend on the above cleanup tasks
+    update_statistics_on_cleanup_end(os::javaTimeNanos());
+  }
   }
 }
 
@@ -411,6 +419,9 @@
     ConcurrentGCThread::safepoint_desynchronize();
   }
 #endif // SERIALGC
+  // record this time so VMThread can keep track how much time has elasped
+  // since last safepoint.
+  _end_of_last_safepoint = os::javaTimeMillis();
 }
 
 bool SafepointSynchronize::is_cleanup_needed() {
@@ -445,24 +456,23 @@
 
 // Various cleaning tasks that should be done periodically at safepoints
 void SafepointSynchronize::do_cleanup_tasks() {
-  jlong cleanup_time;
-
-  // Update fat-monitor pool, since this is a safepoint.
-  if (TraceSafepoint) {
-    cleanup_time = os::javaTimeNanos();
+  {
+    TraceTime t1("deflating idle monitors", TraceSafepointCleanupTime);
+    ObjectSynchronizer::deflate_idle_monitors();
   }
 
-  ObjectSynchronizer::deflate_idle_monitors();
-  InlineCacheBuffer::update_inline_caches();
+  {
+    TraceTime t2("updating inline caches", TraceSafepointCleanupTime);
+    InlineCacheBuffer::update_inline_caches();
+  }
+
   if(UseCounterDecay && CounterDecay::is_decay_needed()) {
+    TraceTime t3("decaying counter", TraceSafepointCleanupTime);
     CounterDecay::decay();
   }
+
+  TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime);
   NMethodSweeper::sweep();
-
-  if (TraceSafepoint) {
-    tty->print_cr("do_cleanup_tasks takes "INT64_FORMAT_W(6) "ms",
-                  (os::javaTimeNanos() - cleanup_time) / MICROUNITS);
-  }
 }
 
 
@@ -979,17 +989,32 @@
 //                     Statistics & Instrumentations
 //
 SafepointSynchronize::SafepointStats*  SafepointSynchronize::_safepoint_stats = NULL;
+jlong  SafepointSynchronize::_safepoint_begin_time = 0;
 int    SafepointSynchronize::_cur_stat_index = 0;
 julong SafepointSynchronize::_safepoint_reasons[VM_Operation::VMOp_Terminating];
 julong SafepointSynchronize::_coalesced_vmop_count = 0;
 jlong  SafepointSynchronize::_max_sync_time = 0;
+jlong  SafepointSynchronize::_max_vmop_time = 0;
+float  SafepointSynchronize::_ts_of_current_safepoint = 0.0f;
 
-// last_safepoint_start_time records the start time of last safepoint.
-static jlong  last_safepoint_start_time = 0;
-static jlong  sync_end_time = 0;
+static jlong  cleanup_end_time = 0;
 static bool   need_to_track_page_armed_status = false;
 static bool   init_done = false;
 
+// Helper method to print the header.
+static void print_header() {
+  tty->print("         vmop                    "
+             "[threads: total initially_running wait_to_block]    ");
+  tty->print("[time: spin block sync cleanup vmop] ");
+
+  // no page armed status printed out if it is always armed.
+  if (need_to_track_page_armed_status) {
+    tty->print("page_armed ");
+  }
+
+  tty->print_cr("page_trap_count");
+}
+
 void SafepointSynchronize::deferred_initialize_stat() {
   if (init_done) return;
 
@@ -1016,19 +1041,6 @@
   if (UseCompilerSafepoints && DeferPollingPageLoopCount >= 0) {
     need_to_track_page_armed_status = true;
   }
-
-  tty->print("     vmop_name               "
-             "[threads: total initially_running wait_to_block] ");
-  tty->print("[time: spin block sync] "
-             "[vmop_time  time_elapsed] ");
-
-  // no page armed status printed out if it is always armed.
-  if (need_to_track_page_armed_status) {
-    tty->print("page_armed ");
-  }
-
-  tty->print_cr("page_trap_count");
-
   init_done = true;
 }
 
@@ -1036,6 +1048,8 @@
   assert(init_done, "safepoint statistics array hasn't been initialized");
   SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
 
+  spstat->_time_stamp = _ts_of_current_safepoint;
+
   VM_Operation *op = VMThread::vm_operation();
   spstat->_vmop_type = (op != NULL ? op->type() : -1);
   if (op != NULL) {
@@ -1054,14 +1068,6 @@
   }  else {
     spstat->_time_to_spin = 0;
   }
-
-  if (last_safepoint_start_time == 0) {
-    spstat->_time_elapsed_since_last_safepoint = 0;
-  } else {
-    spstat->_time_elapsed_since_last_safepoint = _last_safepoint -
-      last_safepoint_start_time;
-  }
-  last_safepoint_start_time = _last_safepoint;
 }
 
 void SafepointSynchronize::update_statistics_on_spin_end() {
@@ -1097,18 +1103,31 @@
   // Records the end time of sync which will be used to calculate the total
   // vm operation time. Again, the real time spending in syncing will be deducted
   // from the start of the sync time later when end_statistics is called.
-  spstat->_time_to_sync = end_time - _last_safepoint;
+  spstat->_time_to_sync = end_time - _safepoint_begin_time;
   if (spstat->_time_to_sync > _max_sync_time) {
     _max_sync_time = spstat->_time_to_sync;
   }
-  sync_end_time = end_time;
+
+  spstat->_time_to_do_cleanups = end_time;
+}
+
+void SafepointSynchronize::update_statistics_on_cleanup_end(jlong end_time) {
+  SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
+
+  // Record how long spent in cleanup tasks.
+  spstat->_time_to_do_cleanups = end_time - spstat->_time_to_do_cleanups;
+
+  cleanup_end_time = end_time;
 }
 
 void SafepointSynchronize::end_statistics(jlong vmop_end_time) {
   SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
 
   // Update the vm operation time.
-  spstat->_time_to_exec_vmop = vmop_end_time -  sync_end_time;
+  spstat->_time_to_exec_vmop = vmop_end_time -  cleanup_end_time;
+  if (spstat->_time_to_exec_vmop > _max_vmop_time) {
+    _max_vmop_time = spstat->_time_to_exec_vmop;
+  }
   // Only the sync time longer than the specified
   // PrintSafepointStatisticsTimeout will be printed out right away.
   // By default, it is -1 meaning all samples will be put into the list.
@@ -1119,40 +1138,42 @@
   } else {
     // The safepoint statistics will be printed out when the _safepoin_stats
     // array fills up.
-    if (_cur_stat_index != PrintSafepointStatisticsCount - 1) {
-      _cur_stat_index ++;
-    } else {
+    if (_cur_stat_index == PrintSafepointStatisticsCount - 1) {
       print_statistics();
       _cur_stat_index = 0;
-      tty->print_cr("");
+    } else {
+      _cur_stat_index++;
     }
   }
 }
 
 void SafepointSynchronize::print_statistics() {
-  int index;
   SafepointStats* sstats = _safepoint_stats;
 
-  for (index = 0; index <= _cur_stat_index; index++) {
+  for (int index = 0; index <= _cur_stat_index; index++) {
+    if (index % 30 == 0) {
+      print_header();
+    }
     sstats = &_safepoint_stats[index];
-    tty->print("%-28s       ["
+    tty->print("%.3f: ", sstats->_time_stamp);
+    tty->print("%-26s       ["
                INT32_FORMAT_W(8)INT32_FORMAT_W(11)INT32_FORMAT_W(15)
-               "]   ",
+               "    ]    ",
                sstats->_vmop_type == -1 ? "no vm operation" :
                VM_Operation::name(sstats->_vmop_type),
                sstats->_nof_total_threads,
                sstats->_nof_initial_running_threads,
                sstats->_nof_threads_wait_to_block);
     // "/ MICROUNITS " is to convert the unit from nanos to millis.
-    tty->print("       ["
-               INT64_FORMAT_W(6)INT64_FORMAT_W(6)INT64_FORMAT_W(6)
-               "]     "
-               "["INT64_FORMAT_W(6)INT64_FORMAT_W(9) "]          ",
+    tty->print("  ["
+               INT64_FORMAT_W(6)INT64_FORMAT_W(6)
+               INT64_FORMAT_W(6)INT64_FORMAT_W(6)
+               INT64_FORMAT_W(6)"    ]  ",
                sstats->_time_to_spin / MICROUNITS,
                sstats->_time_to_wait_to_block / MICROUNITS,
                sstats->_time_to_sync / MICROUNITS,
-               sstats->_time_to_exec_vmop / MICROUNITS,
-               sstats->_time_elapsed_since_last_safepoint / MICROUNITS);
+               sstats->_time_to_do_cleanups / MICROUNITS,
+               sstats->_time_to_exec_vmop / MICROUNITS);
 
     if (need_to_track_page_armed_status) {
       tty->print(INT32_FORMAT"         ", sstats->_page_armed);
@@ -1174,7 +1195,7 @@
   // don't print it out.
   // Approximate the vm op time.
   _safepoint_stats[_cur_stat_index]._time_to_exec_vmop =
-    os::javaTimeNanos() - sync_end_time;
+    os::javaTimeNanos() - cleanup_end_time;
 
   if ( PrintSafepointStatisticsTimeout < 0 ||
        spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) {
@@ -1203,6 +1224,9 @@
                 _coalesced_vmop_count);
   tty->print_cr("Maximum sync time  "INT64_FORMAT_W(5)" ms",
                 _max_sync_time / MICROUNITS);
+  tty->print_cr("Maximum vm operation time (except for Exit VM operation)  "
+                INT64_FORMAT_W(5)" ms",
+                _max_vmop_time / MICROUNITS);
 }
 
 // ------------------------------------------------------------------------------------------------
--- a/src/share/vm/runtime/safepoint.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/safepoint.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -65,6 +65,7 @@
   };
 
   typedef struct {
+    float  _time_stamp;                        // record when the current safepoint occurs in seconds
     int    _vmop_type;                         // type of VM operation triggers the safepoint
     int    _nof_total_threads;                 // total number of Java threads
     int    _nof_initial_running_threads;       // total number of initially seen running threads
@@ -73,14 +74,14 @@
     int    _nof_threads_hit_page_trap;         // total number of threads hitting the page trap
     jlong  _time_to_spin;                      // total time in millis spent in spinning
     jlong  _time_to_wait_to_block;             // total time in millis spent in waiting for to block
+    jlong  _time_to_do_cleanups;               // total time in millis spent in performing cleanups
     jlong  _time_to_sync;                      // total time in millis spent in getting to _synchronized
     jlong  _time_to_exec_vmop;                 // total time in millis spent in vm operation itself
-    jlong  _time_elapsed_since_last_safepoint; // time elasped since last safepoint
   } SafepointStats;
 
  private:
   static volatile SynchronizeState _state;     // Threads might read this flag directly, without acquireing the Threads_lock
-  static volatile int _waiting_to_block;       // No. of threads we are waiting for to block.
+  static volatile int _waiting_to_block;       // number of threads we are waiting for to block
 
   // This counter is used for fast versions of jni_Get<Primitive>Field.
   // An even value means there is no ongoing safepoint operations.
@@ -91,19 +92,22 @@
 public:
   static volatile int _safepoint_counter;
 private:
-
-  static jlong   _last_safepoint;      // Time of last safepoint
+  static long       _end_of_last_safepoint;     // Time of last safepoint in milliseconds
 
   // statistics
-  static SafepointStats*  _safepoint_stats;     // array of SafepointStats struct
-  static int              _cur_stat_index;      // current index to the above array
-  static julong           _safepoint_reasons[]; // safepoint count for each VM op
-  static julong           _coalesced_vmop_count;// coalesced vmop count
-  static jlong            _max_sync_time;       // maximum sync time in nanos
+  static jlong            _safepoint_begin_time;     // time when safepoint begins
+  static SafepointStats*  _safepoint_stats;          // array of SafepointStats struct
+  static int              _cur_stat_index;           // current index to the above array
+  static julong           _safepoint_reasons[];      // safepoint count for each VM op
+  static julong           _coalesced_vmop_count;     // coalesced vmop count
+  static jlong            _max_sync_time;            // maximum sync time in nanos
+  static jlong            _max_vmop_time;            // maximum vm operation time in nanos
+  static float            _ts_of_current_safepoint;  // time stamp of current safepoint in seconds
 
   static void begin_statistics(int nof_threads, int nof_running);
   static void update_statistics_on_spin_end();
   static void update_statistics_on_sync_end(jlong end_time);
+  static void update_statistics_on_cleanup_end(jlong end_time);
   static void end_statistics(jlong end_time);
   static void print_statistics();
   inline static void inc_page_trap_count() {
@@ -140,7 +144,9 @@
   static void handle_polling_page_exception(JavaThread *thread);
 
   // VM Thread interface for determining safepoint rate
-  static long last_non_safepoint_interval()               { return os::javaTimeMillis() - _last_safepoint; }
+  static long last_non_safepoint_interval() {
+    return os::javaTimeMillis() - _end_of_last_safepoint;
+  }
   static bool is_cleanup_needed();
   static void do_cleanup_tasks();
 
--- a/src/share/vm/runtime/sharedRuntime.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -256,7 +256,7 @@
 // The continuation address is the entry point of the exception handler of the
 // previous frame depending on the return address.
 
-address SharedRuntime::raw_exception_handler_for_return_address(address return_address) {
+address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) {
   assert(frame::verify_return_pc(return_address), "must be a return pc");
 
   // the fastest case first
@@ -264,6 +264,8 @@
   if (blob != NULL && blob->is_nmethod()) {
     nmethod* code = (nmethod*)blob;
     assert(code != NULL, "nmethod must be present");
+    // Check if the return address is a MethodHandle call site.
+    thread->set_is_method_handle_exception(code->is_method_handle_return(return_address));
     // native nmethods don't have exception handlers
     assert(!code->is_native_method(), "no exception handler");
     assert(code->header_begin() != code->exception_begin(), "no exception handler");
@@ -289,6 +291,8 @@
     if (blob->is_nmethod()) {
       nmethod* code = (nmethod*)blob;
       assert(code != NULL, "nmethod must be present");
+      // Check if the return address is a MethodHandle call site.
+      thread->set_is_method_handle_exception(code->is_method_handle_return(return_address));
       assert(code->header_begin() != code->exception_begin(), "no exception handler");
       return code->exception_begin();
     }
@@ -309,10 +313,11 @@
 }
 
 
-JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(address return_address))
-  return raw_exception_handler_for_return_address(return_address);
+JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(JavaThread* thread, address return_address))
+  return raw_exception_handler_for_return_address(thread, return_address);
 JRT_END
 
+
 address SharedRuntime::get_poll_stub(address pc) {
   address stub;
   // Look up the code blob
@@ -465,16 +470,6 @@
     t = table.entry_for(catch_pco, -1, 0);
   }
 
-#ifdef COMPILER1
-  if (nm->is_compiled_by_c1() && t == NULL && handler_bci == -1) {
-    // Exception is not handled by this frame so unwind.  Note that
-    // this is not the same as how C2 does this.  C2 emits a table
-    // entry that dispatches to the unwind code in the nmethod.
-    return NULL;
-  }
-#endif /* COMPILER1 */
-
-
   if (t == NULL) {
     tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci);
     tty->print_cr("   Exception:");
@@ -587,7 +582,7 @@
           // 3. Implict null exception in nmethod
 
           if (!cb->is_nmethod()) {
-            guarantee(cb->is_adapter_blob(),
+            guarantee(cb->is_adapter_blob() || cb->is_method_handles_adapter_blob(),
                       "exception happened outside interpreter, nmethods and vtable stubs (1)");
             // There is no handler here, so we will simply unwind.
             return StubRoutines::throw_NullPointerException_at_call_entry();
@@ -892,12 +887,13 @@
   RegisterMap cbl_map(thread, false);
   frame caller_frame = thread->last_frame().sender(&cbl_map);
 
-  CodeBlob* cb = caller_frame.cb();
-  guarantee(cb != NULL && cb->is_nmethod(), "must be called from nmethod");
+  CodeBlob* caller_cb = caller_frame.cb();
+  guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod");
+  nmethod* caller_nm = caller_cb->as_nmethod_or_null();
   // make sure caller is not getting deoptimized
   // and removed before we are done with it.
   // CLEANUP - with lazy deopt shouldn't need this lock
-  nmethodLocker caller_lock((nmethod*)cb);
+  nmethodLocker caller_lock(caller_nm);
 
 
   // determine call info & receiver
@@ -929,6 +925,13 @@
   }
 #endif
 
+  // JSR 292
+  // If the resolved method is a MethodHandle invoke target the call
+  // site must be a MethodHandle call site.
+  if (callee_method->is_method_handle_invoke()) {
+    assert(caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
+  }
+
   // Compute entry points. This might require generation of C2I converter
   // frames, so we cannot be holding any locks here. Furthermore, the
   // computation of the entry points is independent of patching the call.  We
@@ -940,13 +943,12 @@
   StaticCallInfo static_call_info;
   CompiledICInfo virtual_call_info;
 
-
   // Make sure the callee nmethod does not get deoptimized and removed before
   // we are done patching the code.
-  nmethod* nm = callee_method->code();
-  nmethodLocker nl_callee(nm);
+  nmethod* callee_nm = callee_method->code();
+  nmethodLocker nl_callee(callee_nm);
 #ifdef ASSERT
-  address dest_entry_point = nm == NULL ? 0 : nm->entry_point(); // used below
+  address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below
 #endif
 
   if (is_virtual) {
@@ -2077,7 +2079,6 @@
 
 // ---------------------------------------------------------------------------
 // Implementation of AdapterHandlerLibrary
-const char* AdapterHandlerEntry::name = "I2C/C2I adapters";
 AdapterHandlerTable* AdapterHandlerLibrary::_adapters = NULL;
 AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = NULL;
 const int AdapterHandlerLibrary_size = 16*K;
@@ -2129,7 +2130,7 @@
   ResourceMark rm;
 
   NOT_PRODUCT(int code_size);
-  BufferBlob *B = NULL;
+  AdapterBlob* B = NULL;
   AdapterHandlerEntry* entry = NULL;
   AdapterFingerPrint* fingerprint = NULL;
   {
@@ -2179,7 +2180,7 @@
 
     // Create I2C & C2I handlers
 
-    BufferBlob*  buf = buffer_blob(); // the temporary code buffer in CodeCache
+    BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
     if (buf != NULL) {
       CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
       short buffer_locs[20];
@@ -2208,7 +2209,7 @@
       }
 #endif
 
-      B = BufferBlob::create(AdapterHandlerEntry::name, &buffer);
+      B = AdapterBlob::create(&buffer);
       NOT_PRODUCT(code_size = buffer.code_size());
     }
     if (B == NULL) {
@@ -2240,7 +2241,7 @@
     jio_snprintf(blob_id,
                  sizeof(blob_id),
                  "%s(%s)@" PTR_FORMAT,
-                 AdapterHandlerEntry::name,
+                 B->name(),
                  fingerprint->as_string(),
                  B->instructions_begin());
     VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
--- a/src/share/vm/runtime/sharedRuntime.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -96,10 +96,9 @@
   static jdouble dexp(jdouble x);
   static jdouble dpow(jdouble x, jdouble y);
 
-
   // exception handling across interpreter/compiler boundaries
-  static address raw_exception_handler_for_return_address(address return_address);
-  static address exception_handler_for_return_address(address return_address);
+  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);
 
 #ifndef SERIALGC
   // G1 write barriers
@@ -568,9 +567,6 @@
   AdapterHandlerEntry();
 
  public:
-  // The name we give all buffer blobs
-  static const char* name;
-
   address get_i2c_entry()            { return _i2c_entry; }
   address get_c2i_entry()            { return _c2i_entry; }
   address get_c2i_unverified_entry() { return _c2i_unverified_entry; }
--- a/src/share/vm/runtime/thread.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/thread.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1637,6 +1637,9 @@
     JNIHandleBlock::release_block(block);
   }
 
+  // These have to be removed while this is still a valid thread.
+  remove_stack_guard_pages();
+
   if (UseTLAB) {
     tlab().make_parsable(true);  // retire TLAB, if any
   }
@@ -2134,7 +2137,7 @@
   int allocate = os::allocate_stack_guard_pages();
   // warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
 
-  if (allocate && !os::commit_memory((char *) low_addr, len)) {
+  if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {
     warning("Attempt to allocate stack guard pages failed.");
     return;
   }
@@ -2155,7 +2158,7 @@
   size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
 
   if (os::allocate_stack_guard_pages()) {
-    if (os::uncommit_memory((char *) low_addr, len)) {
+    if (os::remove_stack_guard_pages((char *) low_addr, len)) {
       _stack_guard_state = stack_guard_unused;
     } else {
       warning("Attempt to deallocate stack guard pages failed.");
--- a/src/share/vm/runtime/vframeArray.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/vframeArray.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -223,7 +223,7 @@
         break;
       case Deoptimization::Unpack_exception:
         // exception is pending
-        pc = SharedRuntime::raw_exception_handler_for_return_address(pc);
+        pc = SharedRuntime::raw_exception_handler_for_return_address(thread, pc);
         // [phh] We're going to end up in some handler or other, so it doesn't
         // matter what mdp we point to.  See exception_handler_for_exception()
         // in interpreterRuntime.cpp.
--- a/src/share/vm/runtime/vmThread.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/runtime/vmThread.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -25,6 +25,10 @@
 # include "incls/_precompiled.incl"
 # include "incls/_vmThread.cpp.incl"
 
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int);
+HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int);
+
 // Dummy VM operation to act as first element in our circular double-linked list
 class VM_Dummy: public VM_Operation {
   VMOp_Type type() const { return VMOp_Dummy; }
@@ -132,6 +136,10 @@
 //-----------------------------------------------------------------
 // High-level interface
 bool VMOperationQueue::add(VM_Operation *op) {
+
+  HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()),
+                   op->evaluation_mode());
+
   // Encapsulates VM queue policy. Currently, that
   // only involves putting them on the right list
   if (op->evaluate_at_safepoint()) {
@@ -325,7 +333,11 @@
 
   {
     PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
+    HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()),
+                     op->evaluation_mode());
     op->evaluate();
+    HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
+                     op->evaluation_mode());
   }
 
   // Last access of info in _cur_vm_operation!
--- a/src/share/vm/services/dtraceAttacher.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/services/dtraceAttacher.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -135,4 +135,9 @@
   }
 }
 
+void DTrace::set_monitor_dprobes(bool flag) {
+  // explicit setting of DTraceMonitorProbes flag
+  set_bool_flag("DTraceMonitorProbes", flag);
+}
+
 #endif /* SOLARIS */
--- a/src/share/vm/services/dtraceAttacher.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/services/dtraceAttacher.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -41,4 +41,6 @@
   static void detach_all_clients();
   // set ExtendedDTraceProbes flag
   static void set_extended_dprobes(bool value);
+  // set DTraceMonitorProbes flag
+  static void set_monitor_dprobes(bool value);
 };
--- a/src/share/vm/services/management.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/services/management.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -1537,7 +1537,6 @@
     global->type = JMM_VMGLOBAL_TYPE_JSTRING;
   } else {
     global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;
-    assert(false, "Unsupported VMGlobal Type");
     return false;
   }
 
--- a/src/share/vm/utilities/globalDefinitions.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -827,6 +827,8 @@
 #define       badHeapWord       (::badHeapWordVal)
 #define       badJNIHandle      ((oop)::badJNIHandleVal)
 
+// Default TaskQueue size is 16K (32-bit) or 128K (64-bit)
+#define TASKQUEUE_SIZE (NOT_LP64(1<<14) LP64_ONLY(1<<17))
 
 //----------------------------------------------------------------------------------------------------
 // Utility functions for bitfield manipulations
--- a/src/share/vm/utilities/taskqueue.cpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/utilities/taskqueue.cpp	Mon Apr 19 20:41:10 2010 -0700
@@ -31,10 +31,6 @@
 uint ParallelTaskTerminator::_total_peeks = 0;
 #endif
 
-bool TaskQueueSuper::peek() {
-  return _bottom != _age.top();
-}
-
 int TaskQueueSetSuper::randomParkAndMiller(int *seed0) {
   const int a =      16807;
   const int m = 2147483647;
@@ -180,6 +176,13 @@
   }
 }
 
+#ifdef ASSERT
+bool ObjArrayTask::is_valid() const {
+  return _obj != NULL && _obj->is_objArray() && _index > 0 &&
+    _index < objArrayOop(_obj)->length();
+}
+#endif // ASSERT
+
 bool RegionTaskQueueWithOverflow::is_empty() {
   return (_region_queue.size() == 0) &&
          (_overflow_stack->length() == 0);
--- a/src/share/vm/utilities/taskqueue.hpp	Sat Mar 20 11:12:00 2010 -0700
+++ b/src/share/vm/utilities/taskqueue.hpp	Mon Apr 19 20:41:10 2010 -0700
@@ -22,6 +22,7 @@
  *
  */
 
+template <unsigned int N>
 class TaskQueueSuper: public CHeapObj {
 protected:
   // Internal type for indexing the queue; also used for the tag.
@@ -30,10 +31,7 @@
   // The first free element after the last one pushed (mod N).
   volatile uint _bottom;
 
-  enum {
-    N = 1 << NOT_LP64(14) LP64_ONLY(17), // Queue size: 16K or 128K
-    MOD_N_MASK = N - 1                   // To compute x mod N efficiently.
-  };
+  enum { MOD_N_MASK = N - 1 };
 
   class Age {
   public:
@@ -84,12 +82,12 @@
 
   // Returns a number in the range [0..N).  If the result is "N-1", it should be
   // interpreted as 0.
-  uint dirty_size(uint bot, uint top) {
+  uint dirty_size(uint bot, uint top) const {
     return (bot - top) & MOD_N_MASK;
   }
 
   // Returns the size corresponding to the given "bot" and "top".
-  uint size(uint bot, uint top) {
+  uint size(uint bot, uint top) const {
     uint sz = dirty_size(bot, top);
     // Has the queue "wrapped", so that bottom is less than top?  There's a
     // complicated special case here.  A pair of threads could perform pop_local
@@ -111,17 +109,17 @@
 public:
   TaskQueueSuper() : _bottom(0), _age() {}
 
-  // Return "true" if the TaskQueue contains any tasks.
-  bool peek();
+  // Return true if the TaskQueue contains any tasks.
+  bool peek() { return _bottom != _age.top(); }
 
   // Return an estimate of the number of elements in the queue.
   // The "careful" version admits the possibility of pop_local/pop_global
   // races.
-  uint size() {
+  uint size() const {
     return size(_bottom, _age.top());
   }
 
-  uint dirty_size() {
+  uint dirty_size() const {
     return dirty_size(_bottom, _age.top());
   }
 
@@ -132,16 +130,36 @@
 
   // Maximum number of elements allowed in the queue.  This is two less
   // than the actual queue size, for somewhat complicated reasons.
-  uint max_elems() { return N - 2; }
+  uint max_elems() const { return N - 2; }
+
+  // Total size of queue.
+  static const uint total_size() { return N; }
 };
 
-template<class E> class GenericTaskQueue: public TaskQueueSuper {
+template<class E, unsigned int N = TASKQUEUE_SIZE>
+class GenericTaskQueue: public TaskQueueSuper<N> {
+protected:
+  typedef typename TaskQueueSuper<N>::Age Age;
+  typedef typename TaskQueueSuper<N>::idx_t idx_t;
+
+  using TaskQueueSuper<N>::_bottom;
+  using TaskQueueSuper<N>::_age;
+  using TaskQueueSuper<N>::increment_index;
+  using TaskQueueSuper<N>::decrement_index;
+  using TaskQueueSuper<N>::dirty_size;
+
+public:
+  using TaskQueueSuper<N>::max_elems;
+  using TaskQueueSuper<N>::size;
+
 private:
   // Slow paths for push, pop_local.  (pop_global has no fast path.)
   bool push_slow(E t, uint dirty_n_elems);
   bool pop_local_slow(uint localBot, Age oldAge);
 
 public:
+  typedef E element_type;
+
   // Initializes the queue to empty.
   GenericTaskQueue();
 
@@ -172,19 +190,19 @@
   volatile E* _elems;
 };
 
-template<class E>
-GenericTaskQueue<E>::GenericTaskQueue():TaskQueueSuper() {
+template<class E, unsigned int N>
+GenericTaskQueue<E, N>::GenericTaskQueue() {
   assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
 }
 
-template<class E>
-void GenericTaskQueue<E>::initialize() {
+template<class E, unsigned int N>
+void GenericTaskQueue<E, N>::initialize() {
   _elems = NEW_C_HEAP_ARRAY(E, N);
   guarantee(_elems != NULL, "Allocation failed.");
 }
 
-template<class E>
-void GenericTaskQueue<E>::oops_do(OopClosure* f) {
+template<class E, unsigned int N>
+void GenericTaskQueue<E, N>::oops_do(OopClosure* f) {
   // tty->print_cr("START OopTaskQueue::oops_do");
   uint iters = size();
   uint index = _bottom;
@@ -200,21 +218,21 @@
   // tty->print_cr("END OopTaskQueue::oops_do");
 }
 
-
-template<class E>
-bool GenericTaskQueue<E>::push_slow(E t, uint dirty_n_elems) {
+template<class E, unsigned int N>
+bool GenericTaskQueue<E, N>::push_slow(E t, uint dirty_n_elems) {
   if (dirty_n_elems == N - 1) {
     // Actually means 0, so do the push.
     uint localBot = _bottom;
-    _elems[localBot] = t;
+    // g++ complains if the volatile result of the assignment is unused.
+    const_cast<E&>(_elems[localBot] = t);
     OrderAccess::release_store(&_bottom, increment_index(localBot));
     return true;
   }
   return false;
 }
 
-template<class E>
-bool GenericTaskQueue<E>::
+template<class E, unsigned int N>
+bool GenericTaskQueue<E, N>::
 pop_local_slow(uint localBot, Age oldAge) {
   // This queue was observed to contain exactly one element; either this
   // thread will claim it, or a competing "pop_global".  In either case,
@@ -246,8 +264,8 @@
   return false;
 }
 
-template<class E>
-bool GenericTaskQueue<E>::pop_global(E& t) {
+template<class E, unsigned int N>
+bool GenericTaskQueue<E, N>::pop_global(E& t) {
   Age oldAge = _age.get();
   uint localBot = _bottom;
   uint n_elems = size(localBot, oldAge.top());
@@ -255,7 +273,7 @@
     return false;
   }
 
-  t = _elems[oldAge.top()];
+  const_cast<E&>(t = _elems[oldAge.top()]);
   Age newAge(oldAge);
   newAge.increment();
   Age resAge = _age.cmpxchg(newAge, oldAge);
@@ -266,8 +284,8 @@
   return resAge == oldAge;
 }
 
-template<class E>
-GenericTaskQueue<E>::~GenericTaskQueue() {
+template<class E, unsigned int N>
+GenericTaskQueue<E, N>::~GenericTaskQueue() {
   FREE_C_HEAP_ARRAY(E, _elems);
 }
 
@@ -280,16 +298,18 @@
   virtual bool peek() = 0;
 };
 
-template<class E> class GenericTaskQueueSet: public TaskQueueSetSuper {
+template<class T>
+class GenericTaskQueueSet: public TaskQueueSetSuper {
 private:
   uint _n;
-  GenericTaskQueue<E>** _queues;
+  T** _queues;
 
 public:
+  typedef typename T::element_type E;
+
   GenericTaskQueueSet(int n) : _n(n) {
-    typedef GenericTaskQueue<E>* GenericTaskQueuePtr;
+    typedef T* GenericTaskQueuePtr;
     _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n);
-    guarantee(_queues != NULL, "Allocation failure.");
     for (int i = 0; i < n; i++) {
       _queues[i] = NULL;
     }
@@ -299,9 +319,9 @@
   bool steal_best_of_2(uint queue_num, int* seed, E& t);
   bool steal_best_of_all(uint queue_num, int* seed, E& t);
 
-  void register_queue(uint i, GenericTaskQueue<E>* q);
+  void register_queue(uint i, T* q);
 
-  GenericTaskQueue<E>* queue(uint n);
+  T* queue(uint n);
 
   // The thread with queue number "queue_num" (and whose random number seed
   // is at "seed") is trying to steal a task from some other queue.  (It
@@ -313,27 +333,27 @@
   bool peek();
 };
 
-template<class E>
-void GenericTaskQueueSet<E>::register_queue(uint i, GenericTaskQueue<E>* q) {
+template<class T> void
+GenericTaskQueueSet<T>::register_queue(uint i, T* q) {
   assert(i < _n, "index out of range.");
   _queues[i] = q;
 }
 
-template<class E>
-GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(uint i) {
+template<class T> T*
+GenericTaskQueueSet<T>::queue(uint i) {
   return _queues[i];
 }
 
-template<class E>
-bool GenericTaskQueueSet<E>::steal(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal(uint queue_num, int* seed, E& t) {
   for (uint i = 0; i < 2 * _n; i++)
     if (steal_best_of_2(queue_num, seed, t))
       return true;
   return false;
 }
 
-template<class E>
-bool GenericTaskQueueSet<E>::steal_best_of_all(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal_best_of_all(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
     int best_k;
     uint best_sz = 0;
@@ -356,8 +376,8 @@
   }
 }
 
-template<class E>
-bool GenericTaskQueueSet<E>::steal_1_random(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal_1_random(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
     uint k = queue_num;
     while (k == queue_num) k = randomParkAndMiller(seed) % _n;
@@ -372,8 +392,8 @@
   }
 }
 
-template<class E>
-bool GenericTaskQueueSet<E>::steal_best_of_2(uint queue_num, int* seed, E& t) {
+template<class T> bool
+GenericTaskQueueSet<T>::steal_best_of_2(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
     uint k1 = queue_num;
     while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
@@ -394,8 +414,8 @@
   }
 }
 
-template<class E>
-bool GenericTaskQueueSet<E>::peek() {
+template<class T>
+bool GenericTaskQueueSet<T>::peek() {
   // Try all the queues.
   for (uint j = 0; j < _n; j++) {
     if (_queues[j]->peek())
@@ -465,14 +485,16 @@
 #endif
 };
 
-template<class E> inline bool GenericTaskQueue<E>::push(E t) {
+template<class E, unsigned int N> inline bool
+GenericTaskQueue<E, N>::push(E t) {
   uint localBot = _bottom;
   assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
   idx_t top = _age.top();
   uint dirty_n_elems = dirty_size(localBot, top);
-  assert((dirty_n_elems >= 0) && (dirty_n_elems < N), "n_elems out of range.");
+  assert(dirty_n_elems < N, "n_elems out of range.");
   if (dirty_n_elems < max_elems()) {
-    _elems[localBot] = t;
+    // g++ complains if the volatile result of the assignment is unused.
+    const_cast<E&>(_elems[localBot] = t);
     OrderAccess::release_store(&_bottom, increment_index(localBot));
     return true;
   } else {
@@ -480,7 +502,8 @@
   }
 }
 
-template<class E> inline bool GenericTaskQueue<E>::pop_local(E& t) {
+template<class E, unsigned int N> inline bool
+GenericTaskQueue<E, N>::pop_local(E& t) {
   uint localBot = _bottom;
   // This value cannot be N-1.  That can only occur as a result of
   // the assignment to bottom in this method.  If it does, this method
@@ -494,7 +517,7 @@
   // This is necessary to prevent any read below from being reordered
   // before the store just above.
   OrderAccess::fence();
-  t = _elems[localBot];
+  const_cast<E&>(t = _elems[localBot]);
   // This is a second read of "age"; the "size()" above is the first.
   // If there's still at least one element in the queue, based on the
   // "_bottom" and "age" we've read, then there can be no interference with
@@ -511,17 +534,23 @@
 }
 
 typedef oop Task;
-typedef GenericTaskQueue<Task>         OopTaskQueue;
-typedef GenericTaskQueueSet<Task>      OopTaskQueueSet;
+typedef GenericTaskQueue<Task>            OopTaskQueue;
+typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
 
-
-#define COMPRESSED_OOP_MASK  1
+#ifdef _MSC_VER
+#pragma warning(push)
+// warning C4522: multiple assignment operators specified
+#pragma warning(disable:4522)
+#endif
 
 // This is a container class for either an oop* or a narrowOop*.
 // Both are pushed onto a task queue and the consumer will test is_narrow()
 // to determine which should be processed.
 class StarTask {
   void*  _holder;        // either union oop* or narrowOop*
+
+  enum { COMPRESSED_OOP_MASK = 1 };
+
  public:
   StarTask(narrowOop* p) {
     assert(((uintptr_t)p & COMPRESSED_OOP_MASK) == 0, "Information loss!");
@@ -537,20 +566,61 @@
     return (narrowOop*)((uintptr_t)_holder & ~COMPRESSED_OOP_MASK);
   }
 
-  // Operators to preserve const/volatile in assignments required by gcc
-  void operator=(const volatile StarTask& t) volatile { _holder = t._holder; }
+  StarTask& operator=(const StarTask& t) {
+    _holder = t._holder;
+    return *this;
+  }
+  volatile StarTask& operator=(const volatile StarTask& t) volatile {
+    _holder = t._holder;
+    return *this;
+  }
 
   bool is_narrow() const {
     return (((uintptr_t)_holder & COMPRESSED_OOP_MASK) != 0);
   }
 };
 
-typedef GenericTaskQueue<StarTask>     OopStarTaskQueue;
-typedef GenericTaskQueueSet<StarTask>  OopStarTaskQueueSet;
+class ObjArrayTask
+{
+public:
+  ObjArrayTask(oop o = NULL, int idx = 0): _obj(o), _index(idx) { }
+  ObjArrayTask(oop o, size_t idx): _obj(o), _index(int(idx)) {
+    assert(idx <= size_t(max_jint), "too big");
+  }
+  ObjArrayTask(const ObjArrayTask& t): _obj(t._obj), _index(t._index) { }
+
+  ObjArrayTask& operator =(const ObjArrayTask& t) {
+    _obj = t._obj;
+    _index = t._index;
+    return *this;
+  }
+  volatile ObjArrayTask&
+  operator =(const volatile ObjArrayTask& t) volatile {
+    _obj = t._obj;
+    _index = t._index;
+    return *this;
+  }
+
+  inline oop obj()   const { return _obj; }
+  inline int index() const { return _index; }
+
+  DEBUG_ONLY(bool is_valid() const); // Tasks to be pushed/popped must be valid.
+
+private:
+  oop _obj;
+  int _index;
+};
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+typedef GenericTaskQueue<StarTask>            OopStarTaskQueue;
+typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet;
 
 typedef size_t RegionTask;  // index for region
-typedef GenericTaskQueue<RegionTask>    RegionTaskQueue;
-typedef GenericTaskQueueSet<RegionTask> RegionTaskQueueSet;
+typedef GenericTaskQueue<RegionTask>         RegionTaskQueue;
+typedef GenericTaskQueueSet<RegionTaskQueue> RegionTaskQueueSet;
 
 class RegionTaskQueueWithOverflow: public CHeapObj {
  protected:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6663854/Test6663854.java	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,1521 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6663854
+ * @summary assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
+ *
+ * @run main/othervm -Xcomp Test6663854
+ */
+
+// This is a randomly generated test that exposed a crash so don't try
+// to make sense of what's it's doing.  The output produced is likely
+// to be stable but it is not being checked as part of this test.
+
+final class Test6663854_Class_0 {
+    final long var_1 = ((byte)1.2510591E38F & - ~ - - - ~3554133935918431232L) << 'g';
+    final static long var_2 = 662144491976981504L;
+    static byte[] var_3;
+    static byte var_4;
+    static float var_5;
+    final short var_6 = 4156;
+    double var_7;
+    char var_8 = 'F';
+    static long var_9;
+    char var_10;
+
+
+    public Test6663854_Class_0()
+    {
+        var_7 = (var_9 = (var_4 = (var_4 = (byte)~ -var_1)));
+        var_7 = (var_4 = (var_4 = (byte)(var_9 = 690685817))) + ~var_2;
+        long var_17 = 1755837857030316032L;
+        var_8 *= (var_7 = var_6);
+        {
+            var_4 = (var_4 = (byte)var_6);
+        }
+        var_5 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)var_17))));
+        if (false)
+        {
+            var_5 = var_6;
+            var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)3.2446162E38F))))));
+        }
+        else
+        {
+            var_8 &= false ? var_6 : var_6;
+        }
+        ((new Test6663854_Class_0[(byte)+ (var_5 = (var_4 = (byte)'Q'))])[var_4 = (byte)396008820]).var_8++;
+        var_5 = (var_8 ^= var_6 >>> - (var_4 = (byte)var_6)) >= 360526660 ? var_8 : var_8;
+    }
+
+
+
+    protected Object clone()
+    {
+        char var_11 = 'E';
+        var_7 = 1.2181972357945285E308 + var_6 - + (var_7 = 1269180234) * 6.244754764669101E307;
+        var_7 = (var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)var_11)))));
+        {
+            var_4 = (var_4 = (var_4 = (byte)1016847968));
+            (false & true ? "nmot" : "m").charAt((false || !true ? var_6 : var_6) * var_6);
+            var_8 |= var_8-- == (long)(var_7 = (byte)var_2 & ~var_2) ? (var_4 = (var_4 = (var_4 = (var_4 = (byte)1.5012703E38F)))) : (var_4 = (byte)4795604615834685440L);
+            ++var_11;
+            var_5 = (var_9 = (int)var_6 | 302324412 - 1720735728);
+            "yfkasl".replaceAll("xlvn" + "peedfph", "awfbuujts");
+        }
+        var_9 = false ? var_6 : var_6;
+        {
+            final boolean var_12 = false;
+        }
+        var_5 = var_2;
+        {
+            var_9 = ((new byte[(byte)var_6][(byte)1.3719104187525612E308])[var_4 = (byte)var_1])[var_4 = (var_4 = (var_4 = (var_4 = (byte)2.2549062E38F)))] + 889886326;
+        }
+        var_9 = (var_2 | ~var_1) & 848602225;
+        {
+            var_4 = (var_4 = (var_4 = (var_4 = (byte)var_6)));
+        }
+        var_7 = var_6;
+        var_9 = var_6;
+        var_5 = (var_4 = (var_4 = (byte)var_8));
+        var_7 = 964691433430251520L ^ var_6;
+        var_5 = ~2571981928559810560L;
+        return "yvetn".endsWith("dtgstxcu".toLowerCase()) | true | true ? (4.2416016638902373E307 != -3.1295498440444366E307 ? "p" : "ars") : (new Object[(byte)var_1])[(byte)(var_9 = 7519039949758987264L)];
+    }
+
+    public boolean equals(Object obj)
+    {
+        var_5 = 1445825238;
+        {
+            var_7 = 2.221982E38F;
+        }
+        {
+            var_9 = var_6;
+        }
+        var_7 = true ? (var_8 ^= (byte)3588201925057082368L) : (var_7 = var_8);
+        short var_13 = var_6;
+        var_4 = (var_4 = (var_4 = (var_4 = (var_4 = (byte)'L'))));
+        var_13--;
+        return true | !false;
+    }
+
+
+    protected char[] func_0()
+    {
+        if (!true ? !false : false)
+        {
+            var_8 %= -(new double[(byte)197311342][(byte)5.6183004E36F])[(byte)(var_5 = (var_9 = 'l'))][(byte)(var_7 = var_6)] * (1.9583867E38F * + (var_4 = (byte)1566742425));
+            var_8 >>= ~6333520277515092992L | var_8;
+        }
+        else
+        {
+            new String();
+        }
+        {
+            var_7 = (byte)5882830303456225280L % ((var_9 = var_6) << var_1);
+        }
+        var_7 = var_6;
+        float var_14;
+        var_14 = (var_4 = (var_4 = (byte)1081376784));
+        var_8 -= 3.1929636E38F;
+        var_7 = 1.5931970715760934E308;
+        var_4 = true | (!false | (var_7 = 2.4773615E37F) < (byte)(short)825088022) ? (var_4 = (byte)4.3114896E37F) : (byte)var_8;
+        final int var_15 = var_6 >> 1197848918;
+        var_9 = var_15;
+        var_14 = 983699379;
+        var_9 = var_6;
+        return (new char[var_4 = (byte)3.593425789671245E307][(byte)1.6242754453980546E308])[var_4 = (byte)(var_9 = (var_4 = (byte)var_1))];
+    }
+
+    final void func_1(final int arg_0)
+    {
+        var_5 = 6370513305314412544L == -5.201821E37F ? 2.5220462E38F : (var_5 = (byte)'f');
+        ((new Test6663854_Class_0[(byte)1250580004024059904L][(byte)(short)var_8])[(byte)(var_8 ^= 68680455462355968L)][var_4 = (var_4 = (byte)var_2)]).var_8 *= (char)(byte)(var_6 * var_6) <= - (var_7 = (var_7 = var_6)) ? ~5194741848806877184L : var_8;
+        var_5 = !"tshhykoap".endsWith("q") ? arg_0 : 'K';
+        var_8 *= (var_8 -= (var_5 = - (var_5 = var_8)));
+        int var_16;
+    }
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854_Class_0.var_8 = "; result += Test6663854.Printer.print(var_8);
+        result += "\n";
+        result += "Test6663854_Class_0.var_10 = "; result += Test6663854.Printer.print(var_10);
+        result += "\n";
+        result += "Test6663854_Class_0.var_3 = "; result += Test6663854.Printer.print(var_3);
+        result += "\n";
+        result += "Test6663854_Class_0.var_1 = "; result += Test6663854.Printer.print(var_1);
+        result += "\n";
+        result += "Test6663854_Class_0.var_2 = "; result += Test6663854.Printer.print(var_2);
+        result += "\n";
+        result += "Test6663854_Class_0.var_9 = "; result += Test6663854.Printer.print(var_9);
+        result += "\n";
+        result += "Test6663854_Class_0.var_7 = "; result += Test6663854.Printer.print(var_7);
+        result += "\n";
+        result += "Test6663854_Class_0.var_5 = "; result += Test6663854.Printer.print(var_5);
+        result += "\n";
+        result += "Test6663854_Class_0.var_6 = "; result += Test6663854.Printer.print(var_6);
+        result += "\n";
+        result += "Test6663854_Class_0.var_4 = "; result += Test6663854.Printer.print(var_4);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+interface Test6663854_Interface_1 {
+    public boolean func_0();
+    public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3);
+}
+
+
+interface Test6663854_Interface_2 extends Test6663854_Interface_1 {
+}
+
+
+final class Test6663854_Class_3 implements Test6663854_Interface_2, Test6663854_Interface_1 {
+    Object var_18;
+    long var_19;
+    static double var_20;
+    final static float var_21 = 2.0644203E38F;
+    Test6663854_Class_0 var_22;
+    final static byte var_23 = 110;
+    static boolean var_24 = false;
+
+
+    public Test6663854_Class_3()
+    {
+        Test6663854_Class_0.var_5 = new Test6663854_Class_0().var_6;
+        var_22 = (var_22 = (new Test6663854_Class_0[var_23])[var_23]);
+        Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23));
+        char var_37;
+        var_19 = var_23;
+    }
+
+
+    public boolean func_0()
+    {
+        if (var_24 = var_24)
+        {
+            Test6663854_Class_0.var_4 = var_24 ^ (var_24 || (var_24 = false)) ? var_23 : (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23));
+        }
+        else
+        {
+            ((Test6663854_Class_0)(var_18 = new Test6663854_Interface_1[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)][var_23])).var_7 = ((var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "uwt"))).var_8 >>>= (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)));
+            var_24 |= !false;
+        }
+        var_18 = (var_18 = "ymmk");
+        if (var_24)
+        {
+            long var_25;
+            ((Test6663854_Class_0)(var_18 = "wsxqujs")).var_8 >>= 'F';
+            var_24 ^= false;
+        }
+        else
+        {
+            {
+                (var_22 = (Test6663854_Class_0)(var_18 = (var_18 = (var_18 = "lrgiwpwet")))).var_8++;
+            }
+            {
+                var_18 = new String[Test6663854_Class_0.var_4 = var_23];
+            }
+            {
+                new String();
+            }
+            ((var_24 |= var_24) | true ^ false ? (var_22 = (Test6663854_Class_0)(var_18 = "rpmudju")) : (var_22 = (new Test6663854_Class_0[var_23])[var_23])).var_8--;
+            var_24 ^= var_24;
+            var_19 = 206416809;
+            var_20 = 1581809112;
+            Test6663854_Class_0 var_26;
+            Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23);
+        }
+        byte var_27 = 29;
+        short var_28 = 24653;
+        var_22 = (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "umagt")));
+        return var_24;
+    }
+
+    public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+    {
+        {
+            final Test6663854_Class_0 var_29 = (new Test6663854_Class_0[var_23])[arg_2];
+        }
+        var_18 = (var_18 = (var_22 = (Test6663854_Class_0)(var_18 = arg_0)));
+        ++(var_22 = (Test6663854_Class_0)(var_18 = (Test6663854_Class_0)(var_18 = (var_18 = new char[var_23])))).var_8;
+        {
+            (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "xcj"))).var_8 |= arg_1 * (short)6.671469496987355E307;
+            Test6663854_Class_0.var_5 = false ? var_23 : 8012291795221583872L;
+            (var_24 ? (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = arg_0))) : (var_22 = (Test6663854_Class_0)(var_18 = arg_3))).var_8--;
+        }
+        ((new String[var_23][var_23])[var_23][var_23]).compareTo(arg_0);
+        var_18 = (var_18 = arg_0);
+        var_24 &= (var_24 ^= true) & ! !false;
+        {
+            var_18 = "lok";
+        }
+        float var_30 = 2.0346904E38F;
+        var_30 += ((Test6663854_Class_0)(var_18 = new float[var_23])).var_6 + 210775691;
+        final double var_31 = 8.865908414454469E307;
+        var_20 = 'm';
+        var_22 = (Test6663854_Class_0)(var_18 = arg_0);
+        return arg_0;
+    }
+
+
+    protected Object clone()
+    {
+        ((Test6663854_Class_0)(var_18 = new short[var_23])).var_7 = 'M';
+        if (var_24)
+        {
+            var_24 = false;
+            String var_32 = "luigad";
+            ((Test6663854_Class_0.var_5 = 1.2920056E38F) > (Test6663854_Class_0.var_4 = var_23) ? (Test6663854_Class_0)(var_18 = new Test6663854_Interface_1[var_23][var_23]) : (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = new byte[var_23])))).var_10 = 'A';
+            (var_22 = (var_22 = (var_22 = (new Test6663854_Class_0[var_23][var_23])[var_23][var_23]))).var_8 /= ((var_22 = (Test6663854_Class_0)(var_18 = (new short[var_23][var_23][var_23])[var_23])).var_7 = 'h');
+            (var_32 = var_32).toString();
+            var_32.length();
+            var_18 = (var_22 = (var_22 = new Test6663854_Class_0()));
+        }
+        else
+        {
+            Test6663854_Class_0.var_4 = var_23;
+            var_22 = (var_22 = (Test6663854_Class_0)(var_18 = "wbeuae"));
+            float var_33;
+            --(var_22 = (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = (var_18 = "irl"))))).var_8;
+        }
+        Test6663854_Class_0.var_4 = var_23;
+        Test6663854_Class_0.var_5 = true ? ((Test6663854_Class_0)(var_18 = (var_18 = new boolean[Test6663854_Class_0.var_4 = var_23]))).var_8 : 'n';
+        var_24 = (var_24 ^= ((var_22 = (Test6663854_Class_0)(var_18 = "g")).var_6 > ((Test6663854_Class_0)(var_18 = "")).var_6 ? var_24 : true) ? false : (var_24 = var_24)) ? var_24 : false;
+        var_22 = (var_22 = (var_22 = (Test6663854_Class_0)(var_18 = new Test6663854_Interface_2[var_23])));
+        return var_18 = "qrlonljqj";
+    }
+
+    public boolean equals(Object obj)
+    {
+        Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)));
+        Test6663854_Class_0.var_5 = var_23 % (var_22 = (var_22 = (Test6663854_Class_0)obj)).var_6;
+        Test6663854_Class_0.var_5 = (((new Test6663854_Class_0[var_23][var_23][var_23])[var_23])[var_24 | (var_24 &= var_24) ? var_23 : (Test6663854_Class_0.var_4 = var_23)][var_23]).var_8;
+        var_22 = false ? (var_22 = (var_22 = (Test6663854_Class_0)obj)) : (var_22 = new Test6663854_Class_0());
+        Test6663854_Class_0.var_5 = ((new Test6663854_Class_0[var_23])[Test6663854_Class_0.var_4 = var_23]).var_8;
+        if (! !var_24)
+        {
+            var_18 = "";
+            (var_22 = (var_22 = (var_22 = (new Test6663854_Class_0[var_23])[Test6663854_Class_0.var_4 = var_23]))).var_8 >>= true ? ~ (Test6663854_Class_0.var_4 = var_23) : (var_22 = (Test6663854_Class_0)obj).var_8++;
+            (var_24 ? (Test6663854_Class_0)(var_18 = "") : (Test6663854_Class_0)obj).var_8 <<= var_23;
+            Test6663854_Class_0.var_4 = var_23;
+            var_20 = (var_22 = (var_22 = (var_22 = (var_22 = (Test6663854_Class_0)obj)))).var_8;
+        }
+        else
+        {
+            var_19 = ((Test6663854_Class_0)obj).var_6;
+        }
+        (var_24 ? "qyukxpui" : (new String[var_23])[Test6663854_Class_0.var_4 = var_23]).substring(612084215);
+        Test6663854_Class_0.var_5 = 'B';
+        if (!false || false)
+        {
+            Test6663854_Class_0.var_4 = true & var_24 ? var_23 : var_23;
+        }
+        else
+        {
+            "eksoig".lastIndexOf('b' > (var_22 = (Test6663854_Class_0)obj).var_8 | 4782397447545636864L >= (short)'[' ? "qusgbf" : "kvmylvct");
+        }
+        Test6663854_Class_0.var_5 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = var_23)) << var_23;
+        int var_34;
+        var_24 = (var_24 &= (var_24 &= true));
+        var_22 = (var_22 = (var_22 = (var_22 = (Test6663854_Class_0)obj)));
+        Test6663854_Interface_1 var_35 = var_24 & ((var_24 &= var_24) ^ var_24) ? (new Test6663854_Interface_1[var_23])[var_23] : (new Test6663854_Interface_1[var_23][var_23])[var_23][var_23];
+        long var_36 = 1042482863045573632L;
+        return var_24;
+    }
+
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854_Class_3.var_19 = "; result += Test6663854.Printer.print(var_19);
+        result += "\n";
+        result += "Test6663854_Class_3.var_20 = "; result += Test6663854.Printer.print(var_20);
+        result += "\n";
+        result += "Test6663854_Class_3.var_21 = "; result += Test6663854.Printer.print(var_21);
+        result += "\n";
+        result += "Test6663854_Class_3.var_23 = "; result += Test6663854.Printer.print(var_23);
+        result += "\n";
+        result += "Test6663854_Class_3.var_24 = "; result += Test6663854.Printer.print(var_24);
+        result += "\n";
+        result += "Test6663854_Class_3.var_22 = "; result += Test6663854.Printer.print(var_22);
+        result += "\n";
+        result += "Test6663854_Class_3.var_18 = "; result += Test6663854.Printer.print(var_18);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+final class Test6663854_Class_4 implements Test6663854_Interface_1, Test6663854_Interface_2 {
+    long var_38 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_23 < (short)+3417996718812544000L) ? ~543562136204028928L : 1593726438;
+    char var_39;
+    static Test6663854_Interface_2 var_40;
+    Test6663854_Class_3 var_41;
+    final short var_42 = false ? Test6663854_Class_3.var_23 : (short)~Test6663854_Class_0.var_2;
+    byte var_43;
+    static Test6663854_Interface_1[] var_44;
+    final char var_45 = 4.321821176880639E307 < var_42 ? 'o' : 'v';
+
+
+    public Test6663854_Class_4()
+    {
+        Test6663854_Class_0.var_5 = 2137855185;
+        "nueqthqo".length();
+        {
+            Test6663854_Class_0.var_9 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23));
+            Object var_61;
+        }
+        String var_62 = "rirgfphe";
+        ((new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_22 = ((var_41 = (var_41 = new Test6663854_Class_3())).var_22 = new Test6663854_Class_0());
+        {
+            Test6663854_Class_0.var_5 = ((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_42;
+            new Test6663854_Class_0();
+            var_41 = (var_41 = new Test6663854_Class_3());
+            new Test6663854_Class_0().var_8 %= var_38;
+            (var_41 = ((new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = new Test6663854_Class_0();
+            Test6663854_Class_0.var_4 = (Test6663854_Class_3.var_24 |= true) ? (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) : Test6663854_Class_3.var_23;
+            Test6663854_Interface_1 var_63 = ((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[var_43 = (var_43 = Test6663854_Class_3.var_23)])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23];
+            (var_41 = (var_41 = (var_41 = (var_41 = (Test6663854_Class_3)var_63)))).var_18 = var_62;
+        }
+        if (Test6663854_Class_3.var_24 ^= false)
+        {
+            var_40 = (var_40 = new Test6663854_Class_3());
+        }
+        else
+        {
+            var_62 = "agwqc";
+            Test6663854_Class_3.var_24 ^= ((Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24 && Test6663854_Class_3.var_24) & false ? false : !Test6663854_Class_3.var_24) ? false | (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24) : (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 |= ! (Test6663854_Class_3.var_24 |= true)));
+            var_38 *= (Test6663854_Class_3.var_20 = (Test6663854_Class_0.var_5 = var_42 + ((Test6663854_Class_3.var_20 = 5378782303770527744L) <= var_42 ? var_42 : var_42)));
+        }
+        var_38 &= ((var_41 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0()).var_6;
+        var_62 = var_62;
+        (var_41 = new Test6663854_Class_3()).var_18 = ((new Object[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (var_43 = Test6663854_Class_3.var_23))];
+        final short var_64 = (short)'C';
+        ((var_41 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0()).var_8 /= ((var_41 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0()).var_6;
+    }
+
+
+    public boolean func_0()
+    {
+        final boolean var_46 = false;
+        return Test6663854_Class_3.var_24;
+    }
+
+    public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+    {
+        {
+            --(false ? new Test6663854_Class_0() : new Test6663854_Class_0()).var_8;
+            "d".substring(Test6663854_Class_3.var_23 - (arg_2 /= + (Test6663854_Class_3.var_20 = 1483190006) * (Test6663854_Class_3.var_20 = ~Test6663854_Class_3.var_23)), 496015226);
+            {
+                var_41 = new Test6663854_Class_3();
+            }
+            var_38 ^= (! ((Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) && (new boolean[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]) ? arg_1 : (var_39 = var_45)) / var_45;
+            var_38 -= (Test6663854_Class_3.var_20 = (new short[Test6663854_Class_3.var_23])[arg_2]) != (arg_2 ^= new Test6663854_Class_0().var_6 & - (var_38 /= (Test6663854_Class_0.var_5 = var_38))) ? (Test6663854_Class_0.var_5 = - -Test6663854_Class_3.var_21) : arg_2;
+            var_41 = new Test6663854_Class_3();
+            var_40 = Test6663854_Class_3.var_24 ? new Test6663854_Class_3() : new Test6663854_Class_3();
+        }
+        int var_47;
+        (var_41 = new Test6663854_Class_3()).var_18 = "qvph";
+        {
+            ++arg_2;
+        }
+        final Test6663854_Class_3 var_48 = new Test6663854_Class_3();
+        {
+            var_48.var_22 = (Test6663854_Class_0)((var_41 = var_48).var_18 = (var_48.var_22 = (Test6663854_Class_0)(var_48.var_18 = new String[Test6663854_Class_3.var_23])));
+            {
+                final float[] var_49 = (new float[Test6663854_Class_3.var_23][arg_2])[arg_2];
+            }
+            "lcfxrlilw".replace(var_45, (char)(false ? (short)2998890687978943488L : var_42));
+            arg_0.lastIndexOf("mx");
+            final Test6663854_Class_0 var_50 = var_48.var_22 = (var_48.var_22 = (Test6663854_Class_0)((var_41 = var_48).var_18 = var_48));
+            new String();
+            ((Test6663854_Class_3)(var_40 = (var_40 = (var_41 = var_48)))).var_22 = var_50;
+            var_50.var_8 |= arg_2;
+            Test6663854_Class_3.var_20 = + - (Test6663854_Class_3.var_20 = var_42) - var_45 * Test6663854_Class_3.var_21;
+            double var_51 = false ? 1.6389923323715952E308 : (var_39 = var_45);
+            (((new Test6663854_Class_3[arg_2][arg_2])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_18 = (var_48.var_18 = new Test6663854_Class_0[arg_2 %= 2090054678][arg_2]);
+        }
+        {
+            var_47 = (arg_2 |= (((new Test6663854_Class_4[arg_2][arg_2][arg_2])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_42);
+        }
+        ((new Test6663854_Class_4[arg_2][Test6663854_Class_3.var_23])[++arg_2][arg_2 <<= 'c']).var_41 = var_48;
+        var_41 = var_48;
+        Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24 & Test6663854_Class_3.var_24;
+        final boolean var_52 = false;
+        {
+            var_40 = (var_41 = (var_41 = var_48));
+            (false ? var_48 : var_48).var_18 = ((new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][arg_2])[arg_2])[++arg_2][(byte)203097731];
+            var_41 = (var_41 = var_48);
+        }
+        var_38 |= (short)Test6663854_Class_3.var_23;
+        var_40 = var_48;
+        {
+            arg_0.indexOf("lnf", var_47 = (((Test6663854_Class_0)(var_48.var_18 = arg_0)).var_8 <<= (var_39 = var_45)));
+        }
+        final boolean var_53 = true & 1.4130067467800934E308 < (arg_2 |= 'W');
+        var_48.var_18 = (var_41 = var_48);
+        (var_48.var_22 = new Test6663854_Class_0()).var_7 = Test6663854_Class_3.var_23;
+        Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 || var_52) ^ ("axg".startsWith(arg_0, var_47 = (var_47 = var_45)) | var_52);
+        {
+            Test6663854_Class_0.var_5 = 275192701;
+        }
+        Test6663854_Interface_2 var_54;
+        if (true)
+        {
+            var_54 = (var_41 = (var_41 = (var_41 = var_48)));
+        }
+        else
+        {
+            ((Test6663854_Class_0)((var_41 = var_48).var_18 = (var_41 = var_48))).var_7 = var_42;
+        }
+        Test6663854_Class_0.var_5 = --arg_2;
+        ((new String[Test6663854_Class_3.var_23])[var_53 ? arg_2 : arg_2]).length();
+        return arg_0 + "qj";
+    }
+
+
+
+
+    final String func_0(byte arg_0, Test6663854_Class_0 arg_1, final Test6663854_Class_0 arg_2, final Object arg_3)
+    {
+        arg_2.var_7 = (new long[arg_0][arg_0])[Test6663854_Class_3.var_23][arg_0 >>>= 1960882886] % arg_0;
+        Object var_55 = (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[--arg_0]).var_41 = new Test6663854_Class_3()).var_18 = (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24 ? (Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 &= true)) : Test6663854_Class_3.var_24 | Test6663854_Class_3.var_24) ? (var_41 = (var_41 = (Test6663854_Class_3)arg_3)) : arg_3;
+        var_38 >>= ((Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24)) | (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24) ? arg_2.var_6 : (arg_0 -= 1.2264686416488313E308)) != (((new Test6663854_Class_4[arg_0])[arg_0]).var_38 >>>= arg_2.var_8) ? Test6663854_Class_3.var_23 : arg_0;
+        arg_0 += 1826349110 / (Test6663854_Class_0.var_5 = arg_0) + Test6663854_Class_3.var_21;
+        (var_41 = !Test6663854_Class_3.var_24 ? (var_41 = (new Test6663854_Class_3[arg_0])[arg_0]) : (new Test6663854_Class_3[--arg_0])[arg_0]).var_22 = ((new Test6663854_Class_0[arg_0][(byte)9.18575257519393E307][Test6663854_Class_3.var_23])[arg_0])[Test6663854_Class_3.var_23][arg_0];
+        (var_41 = new Test6663854_Class_3()).var_22 = ((var_41 = (var_41 = (var_41 = (var_41 = (var_41 = (Test6663854_Class_3)arg_3))))).var_22 = (arg_1 = arg_2));
+        Test6663854_Class_3.var_20 = Test6663854_Class_3.var_21;
+        var_40 = (var_41 = (Test6663854_Class_3)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[arg_0]);
+        Test6663854_Class_0.var_5 = Test6663854_Class_3.var_24 || (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 &= true)) ? var_42 : arg_1.var_6;
+        Test6663854_Class_0.var_5 = arg_0;
+        {
+            arg_0 %= (short)var_45;
+        }
+        var_55 = arg_1;
+        var_40 = (var_41 = (Test6663854_Class_3.var_24 = false) ? (Test6663854_Class_3)var_55 : (Test6663854_Class_3)arg_3);
+        ((Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_20 = arg_0) == 2.2107098E38F) ? (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[arg_0] : (Test6663854_Class_3)(var_55 = "unofratwy")).var_18 = var_55;
+        return "";
+    }
+
+    private static String func_1(final String arg_0, char arg_1, final boolean arg_2, Test6663854_Class_3 arg_3)
+    {
+        if (!false & Test6663854_Class_3.var_24)
+        {
+            char var_56 = 'C';
+        }
+        else
+        {
+            var_40 = (var_40 = (var_40 = arg_3));
+        }
+        ((new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_7 = 2.4396145E38F + (((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][(byte)Test6663854_Class_0.var_2]).var_43 = Test6663854_Class_3.var_23);
+        if (Test6663854_Class_3.var_24)
+        {
+            arg_3 = arg_3;
+        }
+        else
+        {
+            arg_3 = (arg_3 = arg_3);
+        }
+        ((new Test6663854_Class_4[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_38 /= '`';
+        arg_3 = (arg_3 = arg_3);
+        new Test6663854_Class_0().var_8++;
+        return "qd";
+    }
+
+    private Object func_2(short[][] arg_0, final Test6663854_Interface_2 arg_1)
+    {
+        boolean var_57 = false;
+        Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+        var_40 = arg_1;
+        ((var_41 = (var_41 = (var_41 = (Test6663854_Class_3)arg_1))).var_22 = (Test6663854_Class_0)(((Test6663854_Class_3)arg_1).var_18 = "dxrwk")).var_7 = 'c';
+        if (true)
+        {
+            var_40 = (var_40 = arg_1);
+        }
+        else
+        {
+            var_39 = 'Z';
+        }
+        Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+        var_41 = (Test6663854_Class_3)arg_1;
+        return (var_57 ? (Test6663854_Class_3.var_20 = Test6663854_Class_3.var_23) % 1271549437 : 1.1177259470512304E308) <= 1363316667 ? (new Test6663854_Class_3().var_18 = new String[var_43 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]) : new Test6663854_Class_0();
+    }
+
+    private short func_3()
+    {
+        int var_58 = true ? var_42 : 1438975079;
+        float var_59 = Test6663854_Class_3.var_21;
+        var_43 = Test6663854_Class_3.var_23;
+        (var_41 = (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) ? new Test6663854_Class_0() : new Test6663854_Class_0();
+        var_58++;
+        return Test6663854_Class_3.var_24 ? var_42 : (var_43 = Test6663854_Class_3.var_23);
+    }
+
+    protected void func_4(final long arg_0, Test6663854_Class_0 arg_1, long arg_2)
+    {
+        ++arg_2;
+        (arg_1 = (arg_1 = (arg_1 = arg_1))).var_8 /= var_42;
+        --arg_2;
+        final Test6663854_Interface_1 var_60 = ((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[var_43 = Test6663854_Class_3.var_23])[var_43 = Test6663854_Class_3.var_23];
+        (true ? (Test6663854_Class_3)var_60 : (Test6663854_Class_3)var_60).var_22 = (Test6663854_Class_0)((var_41 = (Test6663854_Class_3)(var_40 = (Test6663854_Class_3)var_60)).var_18 = (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_23 == var_38) ? "xo" : "uocm");
+        var_38 >>= (((Test6663854_Class_3)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = (new Test6663854_Class_0[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_8++;
+    }
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854_Class_4.var_39 = "; result += Test6663854.Printer.print(var_39);
+        result += "\n";
+        result += "Test6663854_Class_4.var_45 = "; result += Test6663854.Printer.print(var_45);
+        result += "\n";
+        result += "Test6663854_Class_4.var_44 = "; result += Test6663854.Printer.print(var_44);
+        result += "\n";
+        result += "Test6663854_Class_4.var_38 = "; result += Test6663854.Printer.print(var_38);
+        result += "\n";
+        result += "Test6663854_Class_4.var_40 = "; result += Test6663854.Printer.print(var_40);
+        result += "\n";
+        result += "Test6663854_Class_4.var_42 = "; result += Test6663854.Printer.print(var_42);
+        result += "\n";
+        result += "Test6663854_Class_4.var_43 = "; result += Test6663854.Printer.print(var_43);
+        result += "\n";
+        result += "Test6663854_Class_4.var_41 = "; result += Test6663854.Printer.print(var_41);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+class Test6663854_Class_5 implements Test6663854_Interface_1 {
+    final static char var_65 = 'S';
+    static Test6663854_Interface_2 var_66;
+    static Test6663854_Class_3 var_67;
+
+
+    public Test6663854_Class_5()
+    {
+        {
+            ((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[((Test6663854_Class_4)(new Object[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_43 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).func_0();
+        }
+        Test6663854_Class_0.var_5 = 1409421143;
+        Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = false);
+        Test6663854_Class_0.var_5 = 3.1496384E38F / (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_45 - (Test6663854_Class_3.var_23 + Test6663854_Class_3.var_23));
+        ((new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_18 = (new Object[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+        var_66 = (Test6663854_Class_4.var_40 = (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24)) || false ? new Test6663854_Class_3() : new Test6663854_Class_3());
+    }
+
+
+    public boolean func_0()
+    {
+        {
+            Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+        }
+        Test6663854_Class_0.var_5 = (new char[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+        var_66 = (Test6663854_Class_4.var_40 = new Test6663854_Class_3());
+        Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+        ((var_67 = (var_67 = new Test6663854_Class_3())).var_22 = (Test6663854_Class_0)(new Test6663854_Class_3().var_18 = (new Test6663854_Class_3().var_22 = (new Test6663854_Class_3().var_22 = new Test6663854_Class_0())))).var_8++;
+        Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+        return (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24) ? (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) : (Test6663854_Class_3.var_24 = true);
+    }
+
+    public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+    {
+        ((true | (Test6663854_Class_3.var_24 |= true)) ^ false ? (new Test6663854_Class_0[(byte)arg_1])[arg_2--] : new Test6663854_Class_0()).var_8 <<= 2320675830599883776L;
+        arg_2 -= ~ (Test6663854_Class_3.var_24 ? ~4954934861909065728L : 5155213238651986944L);
+        ((Test6663854_Class_4)((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[arg_2 >>>= 1308733456])[Test6663854_Class_3.var_23]).var_43 = arg_2;
+        Test6663854_Class_0.var_5 = Test6663854_Class_3.var_21;
+        {
+            String var_68;
+            float var_69 = Test6663854_Class_3.var_21 * new Test6663854_Class_0().var_6;
+            ++arg_2;
+            Test6663854_Class_0.var_9 = arg_2;
+            --arg_2;
+            var_68 = arg_0;
+            final long[] var_70 = new long[arg_2 /= 8889610108908524544L];
+            Test6663854_Class_4 var_71;
+        }
+        new Test6663854_Class_4().var_38++;
+        Test6663854_Class_3 var_72;
+        (((new Test6663854_Class_4[arg_2 *= var_65][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[arg_2])[arg_2 ^= arg_2][Test6663854_Class_3.var_23]).var_38--;
+        new Test6663854_Class_3();
+        (((new Test6663854_Class_4[arg_2 /= 7.692983E37F][Test6663854_Class_3.var_23])[arg_2])[Test6663854_Class_3.var_23]).var_38 |= arg_1;
+        Test6663854_Class_3.var_24 ^= "dlhn".startsWith(true ? "tad" : "bssdfvig", 1125165775) ? Test6663854_Class_3.var_24 : true;
+        Test6663854_Class_3.var_20 = new Test6663854_Class_0().var_8;
+        Test6663854_Class_4.var_40 = (Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+        var_72 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][arg_2])[arg_2][arg_2];
+        Test6663854_Class_0.var_5 = 8634870161778523136L;
+        {
+            Test6663854_Class_0.var_5 = ~4420139622226571264L;
+            Test6663854_Class_3.var_24 &= (var_72 = (var_67 = (new Test6663854_Class_3[arg_2][Test6663854_Class_3.var_23])[arg_2][arg_2])).func_0();
+            arg_2 >>= false ? 'H' : ']';
+        }
+        switch (arg_2)
+        {
+            case 72:
+                String var_73 = arg_0;
+                break;
+
+            default:
+
+        }
+        ((Test6663854_Class_0)((var_72 = (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[arg_2]).var_18 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])).var_7 = ((new Test6663854_Class_0[arg_2])[arg_2]).var_6 + Test6663854_Class_3.var_23;
+        var_67 = (var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[(byte)7.184837949183326E307][arg_2 ^= 2188582676874919936L]);
+        return ((Test6663854_Class_3.var_24 = new Test6663854_Class_0().var_6 >= (short)3.4944631475014644E307) ? Test6663854_Class_3.var_24 : (Test6663854_Class_3.var_24 ? (Test6663854_Class_3.var_24 = false) : !Test6663854_Class_3.var_24)) ? "y" : arg_0;
+    }
+
+
+
+
+    private final static float func_0(boolean arg_0)
+    {
+        {
+            new String();
+            {
+                new String();
+            }
+            ((Test6663854_Class_3)(new Object[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[(new byte[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_18 = (new Object[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[(byte)1.577204008065932E308][Test6663854_Class_3.var_23];
+            int var_74;
+            new String();
+            Test6663854_Class_0.var_5 = ((Test6663854_Class_0)(new Object[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_1;
+            new String();
+            new String();
+            new String();
+            var_74 = '_';
+            new Test6663854_Class_0();
+            Test6663854_Class_3 var_75 = var_67 = (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_41 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]);
+        }
+        if (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24))
+        {
+            new String();
+            arg_0 &= ~ (((new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_38 /= Test6663854_Class_3.var_23) < 2.1129417E38F;
+        }
+        else
+        {
+            Test6663854_Class_3.var_24 &= false & arg_0 ? false : (Test6663854_Class_3.var_24 &= true);
+        }
+        new Test6663854_Class_0().var_8 ^= 682270015;
+        Test6663854_Class_4.var_40 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+        new Test6663854_Class_0();
+        new String();
+        new Test6663854_Class_0();
+        new Test6663854_Class_3().var_22 = new Test6663854_Class_0();
+        Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+        new Test6663854_Class_0().var_8++;
+        new Test6663854_Class_0();
+        Test6663854_Interface_1 var_76;
+        return Test6663854_Class_3.var_21;
+    }
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854_Class_5.var_65 = "; result += Test6663854.Printer.print(var_65);
+        result += "\n";
+        result += "Test6663854_Class_5.var_66 = "; result += Test6663854.Printer.print(var_66);
+        result += "\n";
+        result += "Test6663854_Class_5.var_67 = "; result += Test6663854.Printer.print(var_67);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+class Test6663854_Class_6 implements Test6663854_Interface_1, Test6663854_Interface_2 {
+    static long var_77;
+    final byte var_78 = Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+    long var_79;
+    static Test6663854_Class_4 var_80;
+    static long var_81 = 1365276905537306624L;
+    static Test6663854_Class_3 var_82;
+
+
+    public Test6663854_Class_6()
+    {
+        Test6663854_Class_0.var_5 = Test6663854_Class_3.var_24 ? "bdouannkn".charAt(373674594) : (char)2612074035904901120L;
+        if (Test6663854_Class_3.var_24)
+        {
+            ++var_81;
+            Test6663854_Class_0.var_4 = (new byte[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[var_78];
+            var_81++;
+        }
+        else
+        {
+            (var_80 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = var_78]).var_41 = (((Test6663854_Class_4)(new Object[Test6663854_Class_3.var_23])[var_78]).var_41 = new Test6663854_Class_3());
+            var_81--;
+            ((new Test6663854_Class_0[var_78])[var_78]).equals((Test6663854_Class_5.var_67 = (Test6663854_Class_3)(new Test6663854_Interface_2[var_78])[var_78]).var_18 = Test6663854_Class_3.var_23 <= var_78 ? "uvoxke" : new String());
+            {
+                Test6663854_Class_5.var_66 = (new Test6663854_Interface_2[var_78])[((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78];
+            }
+            "huxqcdmii".compareTo("owtdmma");
+            Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)));
+            var_81--;
+        }
+        {
+            Test6663854_Class_5[][] var_85;
+        }
+        Test6663854_Class_5.var_66 = (new Test6663854_Interface_2[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+        if (Test6663854_Class_3.var_24 || Test6663854_Class_3.var_24)
+        {
+            var_82 = (new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[var_78][Test6663854_Class_3.var_23];
+            Test6663854_Class_0.var_5 = ++var_81;
+            Test6663854_Class_0.var_5 = Test6663854_Class_3.var_24 ? 'n' : Test6663854_Class_5.var_65;
+        }
+        else
+        {
+            new Test6663854_Class_0();
+        }
+        Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+        Test6663854_Class_5.var_66 = new Test6663854_Class_3();
+        Test6663854_Class_3 var_86 = (var_80 = (var_80 = (var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_41 = (var_82 = (Test6663854_Class_5.var_67 = ((new Test6663854_Class_3[Test6663854_Class_3.var_23][var_78][Test6663854_Class_3.var_23])[var_78])[var_78][Test6663854_Class_3.var_23]));
+        Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) ? (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) : (Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24);
+        var_86.var_22 = (new Test6663854_Class_0[var_78][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][var_78];
+        (Test6663854_Class_3.var_24 ? "evayayw" : "ndcq").startsWith("hwlik" + "tnhfsky");
+        var_86 = var_86;
+    }
+
+
+    public boolean func_0()
+    {
+        Test6663854_Class_4.var_40 = (Test6663854_Class_5.var_67 = (new Test6663854_Class_3[var_78])[Test6663854_Class_3.var_23]);
+        return Test6663854_Class_0.var_2 != (((new Test6663854_Class_0[var_78])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_7 = Test6663854_Class_3.var_23);
+    }
+
+    public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+    {
+        Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24;
+        Test6663854_Class_0.var_5 = var_78;
+        char var_83;
+        (Test6663854_Class_5.var_67 = (Test6663854_Class_5.var_67 = (Test6663854_Class_3)(new Test6663854_Interface_1[var_78])[Test6663854_Class_3.var_23])).var_18 = new Test6663854_Class_0[arg_2];
+        Test6663854_Class_4 var_84;
+        var_81++;
+        return arg_0;
+    }
+
+
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854_Class_6.var_77 = "; result += Test6663854.Printer.print(var_77);
+        result += "\n";
+        result += "Test6663854_Class_6.var_79 = "; result += Test6663854.Printer.print(var_79);
+        result += "\n";
+        result += "Test6663854_Class_6.var_81 = "; result += Test6663854.Printer.print(var_81);
+        result += "\n";
+        result += "Test6663854_Class_6.var_78 = "; result += Test6663854.Printer.print(var_78);
+        result += "\n";
+        result += "Test6663854_Class_6.var_80 = "; result += Test6663854.Printer.print(var_80);
+        result += "\n";
+        result += "Test6663854_Class_6.var_82 = "; result += Test6663854.Printer.print(var_82);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+final class Test6663854_Class_7 extends Test6663854_Class_5 implements Test6663854_Interface_2 {
+    final float var_87 = 1.1671899E38F;
+    static char var_88 = var_65;
+    float var_89 = 2.166908E37F;
+
+
+    public Test6663854_Class_7()
+    {
+        var_88--;
+        (Test6663854_Class_5.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).equals(((Test6663854_Class_3)(Test6663854_Class_4.var_40 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])).var_18 = "nycb");
+        Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24 ^ false);
+        Test6663854_Class_3.var_24 ^= true;
+        var_88--;
+        Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+        if (false)
+        {
+            Test6663854_Class_4.var_40 = (new Test6663854_Interface_2[Test6663854_Class_3.var_23])[((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78];
+        }
+        else
+        {
+            --Test6663854_Class_6.var_81;
+        }
+        Test6663854_Class_6.var_81--;
+        ++Test6663854_Class_6.var_81;
+        if (Test6663854_Class_3.var_24 = !Test6663854_Class_3.var_24)
+        {
+            --var_88;
+            Test6663854_Class_5.var_66 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+            Test6663854_Class_6.var_81 &= 1451013276;
+            var_88--;
+        }
+        else
+        {
+            var_88 >>= --var_88;
+        }
+        Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24;
+        Test6663854_Class_6.var_81--;
+        Test6663854_Class_6.var_81++;
+        --Test6663854_Class_6.var_81;
+        ((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_41 = new Test6663854_Class_3();
+    }
+
+
+
+
+    public final Test6663854_Class_4 func_0(int arg_0)
+    {
+        --arg_0;
+        {
+            switch ((char)var_89)
+            {
+                case 'R':
+
+            }
+            ++(Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_38;
+            ++var_88;
+            Test6663854_Class_5.var_66 = ~Test6663854_Class_6.var_81 % Test6663854_Class_6.var_81 != (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) ? (Test6663854_Class_6.var_82 = (var_67 = new Test6663854_Class_3())) : new Test6663854_Class_3();
+        }
+        (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])).var_38 &= new Test6663854_Class_0().var_6;
+        Test6663854_Interface_1 var_90 = ((new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23];
+        (Test6663854_Class_5.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = new Test6663854_Class_0();
+        if (true)
+        {
+            ((Test6663854_Class_3)(Test6663854_Interface_2)var_90).var_18 = (((Test6663854_Class_3)var_90).var_22 = new Test6663854_Class_0());
+        }
+        else
+        {
+            ++((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90)).var_45 > 7.093005581228189E307 ? (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90)) : (Test6663854_Class_4)(var_90 = (Test6663854_Class_3)var_90)).var_38;
+        }
+        var_67 = (Test6663854_Class_3.var_24 ^= true) ^ true ? (Test6663854_Class_6.var_82 = (Test6663854_Class_3)var_90) : (Test6663854_Class_3)var_90;
+        {
+            {
+                var_90 = (var_90 = (Test6663854_Class_5)var_90);
+            }
+            Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 ? !false : true) ? (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24))) : ! !Test6663854_Class_3.var_24 && false);
+            Test6663854_Class_0 var_91;
+            Test6663854_Class_4.var_40 = (Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) && (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) | ! (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24)) ? (+Test6663854_Class_3.var_21 != 4.6479454E37F ? (Test6663854_Class_6)(Test6663854_Interface_2)var_90 : (Test6663854_Class_6)var_90) : (new Test6663854_Class_6[Test6663854_Class_3.var_23])[((Test6663854_Class_6)(Test6663854_Class_5.var_66 = (Test6663854_Interface_2)var_90)).var_78];
+        }
+        arg_0 |= ((((Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90).var_41 = (((Test6663854_Class_4)var_90).var_41 = (Test6663854_Class_3)var_90)).var_22 = new Test6663854_Class_0()).var_8 += (Test6663854_Class_3.var_20 = new Test6663854_Class_0().var_1));
+        {
+            (Test6663854_Class_6.var_82 = (new Test6663854_Class_3[((Test6663854_Class_6)var_90).var_78])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_18 = ((Test6663854_Class_3.var_24 ^ (!false & Test6663854_Class_3.var_24 ? Test6663854_Class_3.var_24 : (Test6663854_Class_3.var_24 ^= true)) ? (Test6663854_Class_3)var_90 : (Test6663854_Class_3)(Test6663854_Interface_2)var_90).var_18 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)var_90)).var_41 = (Test6663854_Class_3)(((Test6663854_Class_3)(Test6663854_Class_5.var_66 = (Test6663854_Class_3)var_90)).var_18 = (((Test6663854_Class_3)(Test6663854_Interface_2)var_90).var_18 = (Test6663854_Class_3)var_90))));
+        }
+        {
+            arg_0++;
+        }
+        Test6663854_Interface_2 var_92;
+        {
+            ((Test6663854_Class_5.var_67 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_4)(var_92 = (Test6663854_Class_3)var_90)).var_41 = (Test6663854_Class_5.var_67 = (Test6663854_Class_3)var_90))).var_22 = ((Test6663854_Class_5.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_22 = ((Test6663854_Class_6.var_82 = (((Test6663854_Class_4)var_90).var_41 = (Test6663854_Class_3)var_90)).var_22 = (Test6663854_Class_0)((Test6663854_Class_5.var_67 = (Test6663854_Class_3)var_90).var_18 = (Test6663854_Class_5)var_90)))).var_7 = Test6663854_Class_3.var_21;
+        }
+        arg_0 &= ((var_67 = (var_67 = new Test6663854_Class_3())).var_22 = (new Test6663854_Class_0[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_1 / 2084775982;
+        Test6663854_Class_3.var_20 = (Test6663854_Class_3.var_24 = false) ^ true ? Test6663854_Class_0.var_2 : var_88;
+        return Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[((Test6663854_Class_6)var_90).var_78];
+    }
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854_Class_7.var_65 = "; result += Test6663854.Printer.print(var_65);
+        result += "\n";
+        result += "Test6663854_Class_7.var_88 = "; result += Test6663854.Printer.print(var_88);
+        result += "\n";
+        result += "Test6663854_Class_7.var_87 = "; result += Test6663854.Printer.print(var_87);
+        result += "\n";
+        result += "Test6663854_Class_7.var_89 = "; result += Test6663854.Printer.print(var_89);
+        result += "\n";
+        result += "Test6663854_Class_7.var_66 = "; result += Test6663854.Printer.print(var_66);
+        result += "\n";
+        result += "Test6663854_Class_7.var_67 = "; result += Test6663854.Printer.print(var_67);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+final class Test6663854_Class_8 implements Test6663854_Interface_1 {
+    long var_93 = ++Test6663854_Class_6.var_81;
+    short var_94 = (short)'H';
+    float var_95;
+    Test6663854_Interface_1 var_96;
+    final static float var_97 = 2.43397E38F;
+    final static long var_98 = 7461452158234510336L;
+    static Test6663854_Class_7[] var_99;
+
+
+    public Test6663854_Class_8()
+    {
+        Test6663854_Class_6 var_103;
+        Test6663854_Class_3.var_20 = (Test6663854_Class_3.var_20 = var_94 / ~Test6663854_Class_3.var_23);
+        if (false)
+        {
+            Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24;
+        }
+        else
+        {
+            Test6663854_Class_3.var_20 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+            --Test6663854_Class_7.var_88;
+        }
+        final boolean[] var_104 = new boolean[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23];
+        Test6663854_Class_3.var_24 &= false & (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24);
+    }
+
+
+    public boolean func_0()
+    {
+        Test6663854_Class_7.var_88--;
+        Test6663854_Class_7.var_88--;
+        (((new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_7 = 1.2337083709828518E307;
+        Test6663854_Class_7.var_88++;
+        if (Test6663854_Class_3.var_24)
+        {
+            byte var_100 = 25;
+            "lwmbav".toLowerCase();
+            Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 |= false) & ((Test6663854_Class_3.var_24 = true) ^ Test6663854_Class_3.var_24 ? (Test6663854_Class_3.var_24 ^= Test6663854_Class_3.var_24) : Test6663854_Class_3.var_24);
+        }
+        else
+        {
+            long var_101;
+            new Test6663854_Class_0().var_7 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+            Test6663854_Class_7.var_88++;
+            ++Test6663854_Class_6.var_81;
+            Test6663854_Class_7.var_88 |= 1083041050566936576L;
+            Test6663854_Class_7.var_88--;
+        }
+        var_94 ^= (var_94 = (var_94 *= 1.9072213520938263E307));
+        var_94++;
+        boolean var_102 = true;
+        ++Test6663854_Class_7.var_88;
+        Test6663854_Class_7.var_88 += (((new Test6663854_Class_7[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_87;
+        ((new Test6663854_Class_7[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_89 /= (new double[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23] * var_97;
+        return (Test6663854_Class_3.var_24 = (var_102 &= Test6663854_Class_3.var_24 & true)) ? false : Test6663854_Class_3.var_24;
+    }
+
+    public String func_1(final String arg_0, final long arg_1, byte arg_2, char[][] arg_3)
+    {
+        Test6663854_Class_7.var_88--;
+        --Test6663854_Class_7.var_88;
+        return arg_0;
+    }
+
+
+
+    private Test6663854_Class_0 func_0(Test6663854_Class_0 arg_0)
+    {
+        if (!Test6663854_Class_3.var_24)
+        {
+            Test6663854_Class_7.var_88 ^= (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) << ~Test6663854_Class_0.var_2;
+        }
+        else
+        {
+            (Test6663854_Class_6.var_82 = (Test6663854_Class_7.var_67 = (Test6663854_Class_3)(new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])).var_22 = (((new Test6663854_Class_3[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_22 = (arg_0 = arg_0));
+        }
+        if ((Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) < Test6663854_Class_3.var_21)
+        {
+            Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 ^= (arg_0.var_6 ^ Test6663854_Class_7.var_88++) != (long)"y".codePointAt((int)var_94)) | false;
+        }
+        else
+        {
+            ++Test6663854_Class_7.var_88;
+        }
+        var_94 >>= (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23);
+        {
+            Test6663854_Class_7.var_66 = (Test6663854_Class_6)(var_96 = new Test6663854_Class_3());
+        }
+        arg_0.var_8 = 'u';
+        var_94 ^= arg_0.var_8;
+        ++var_94;
+        Test6663854_Class_7.var_88++;
+        var_94 += (Test6663854_Class_3.var_20 = '^');
+        return arg_0;
+    }
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854_Class_8.var_99 = "; result += Test6663854.Printer.print(var_99);
+        result += "\n";
+        result += "Test6663854_Class_8.var_93 = "; result += Test6663854.Printer.print(var_93);
+        result += "\n";
+        result += "Test6663854_Class_8.var_98 = "; result += Test6663854.Printer.print(var_98);
+        result += "\n";
+        result += "Test6663854_Class_8.var_95 = "; result += Test6663854.Printer.print(var_95);
+        result += "\n";
+        result += "Test6663854_Class_8.var_97 = "; result += Test6663854.Printer.print(var_97);
+        result += "\n";
+        result += "Test6663854_Class_8.var_94 = "; result += Test6663854.Printer.print(var_94);
+        result += "\n";
+        result += "Test6663854_Class_8.var_96 = "; result += Test6663854.Printer.print(var_96);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+public class Test6663854 {
+    static short var_105 = 19709;
+    static int var_106 = (((Test6663854_Class_3.var_24 = (Test6663854_Class_3.var_24 = false)) | true) & (false || !false) ? ! (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24) : Test6663854_Class_3.var_24 | false) ? (short)5430142769559462912L : Test6663854_Class_3.var_23 << Test6663854_Class_3.var_23;
+    boolean var_107 = false;
+
+
+    private static long func_0(final boolean arg_0)
+    {
+        {
+            Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_2[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+        }
+        var_105++;
+        ((new Test6663854_Class_7[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)][((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78]).func_0();
+        byte var_108 = 107;
+        return Test6663854_Class_8.var_98 << ((new Test6663854_Class_4[var_108][Test6663854_Class_3.var_23])[var_108][Test6663854_Class_3.var_24 ? var_108 : var_108--]).var_42;
+    }
+
+    protected final long func_1(char[] arg_0, Object arg_1, String arg_2, final int arg_3)
+    {
+        (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)))).var_43 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)))))).var_43 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23));
+        {
+            Test6663854_Class_6.var_82 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_41 = (((new Test6663854[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_107 ^= var_107) ? (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] : (Test6663854_Class_3)arg_1);
+        }
+        Test6663854_Class_7.var_88 += (Test6663854_Class_6.var_81 >>>= (var_107 &= var_107) | var_107 ? (int)- ~Test6663854_Class_6.var_81 : Test6663854_Class_3.var_23);
+        short var_109 = 11276;
+        final Test6663854_Class_8 var_110 = (Test6663854_Class_3.var_24 ^ (Test6663854_Class_3.var_24 = !true) ? 5788412835121658880L : var_109--) * (298795405395535872L << (((Test6663854_Class_0)arg_1).var_1 << (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) != (var_107 ? var_109 : var_105) ? (Test6663854_Class_8)(arg_1 = arg_1) : ((Test6663854_Class_3.var_24 &= ! !var_107) ? new Test6663854_Class_8() : new Test6663854_Class_8());
+        new Test6663854_Class_4().var_43 = Test6663854_Class_3.var_24 ^ Test6663854_Class_3.var_24 ^ Test6663854_Class_3.var_24 ? (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)) : (new byte[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+        Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)));
+        Test6663854_Class_3.var_20 = (var_105 ^= (var_106 *= ((Test6663854_Class_7)arg_1).var_87 - ~Test6663854_Class_3.var_23));
+        Test6663854_Class_5 var_111;
+        Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1));
+        {
+            (arg_2 = "eiprceumt").compareTo(arg_2 = (arg_2 = "roae"));
+        }
+        if (false)
+        {
+            final Test6663854_Class_8 var_112 = var_110;
+            (true | (false && false) ? (Test6663854_Class_3)arg_1 : ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_41 = (Test6663854_Class_6.var_82 = (Test6663854_Class_3)(var_110.var_96 = var_112)))).var_18 = var_110;
+        }
+        else
+        {
+            (Test6663854_Class_3.var_24 ? "jpunp" : "giappofq").concat(arg_2 = (arg_2 = arg_2));
+        }
+        {
+            Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24;
+        }
+        var_110.var_96 = (Test6663854_Class_7)(var_110.var_96 = (Test6663854_Class_7)arg_1);
+        {
+            ((var_107 ^= !var_107) && (!Test6663854_Class_3.var_24 | (Test6663854_Class_3.var_24 |= true) ? !false : !true) ? (Test6663854_Class_4)arg_1 : (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_41 = (((var_107 &= (var_107 &= (var_107 &= (Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24))))) ? (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1) : (Test6663854_Class_4)(Test6663854_Class_4.var_40 = (Test6663854_Class_7)arg_1)).var_41 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)))).var_41 = false || Test6663854_Class_3.var_24 ? (Test6663854_Class_3)arg_1 : (Test6663854_Class_3)arg_1));
+        }
+        Test6663854_Class_5.var_66 = false ? (new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23] : new Test6663854_Class_6();
+        var_105++;
+        arg_1 = (var_111 = new Test6663854_Class_7());
+        ((true ? (Test6663854_Class_3)arg_1 : (Test6663854_Class_3)arg_1).var_22 = (new Test6663854_Class_0[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_8 >>= (var_106 /= ((Test6663854_Class_4)arg_1).var_42) - ((Test6663854_Class_3.var_24 ? (Test6663854_Class_4)arg_1 : (Test6663854_Class_4)arg_1).var_43 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1))).var_43 = new Test6663854_Class_6().var_78));
+        return 5795172173382514688L | (((var_107 &= (Test6663854_Class_3.var_24 |= false) | Test6663854_Class_3.var_24) ? (Test6663854_Class_4)arg_1 : (Test6663854_Class_6.var_80 = (Test6663854_Class_4)arg_1)).var_43 = Test6663854_Class_3.var_23);
+    }
+
+    public static String execute()
+    {
+        try {
+            Test6663854 t = new Test6663854();
+            try { t.test(); }
+            catch(Throwable e) { }
+            try { return t.toString(); }
+            catch (Throwable e) { return "Error during result conversion to String"; }
+        } catch (Throwable e) { return "Error during test execution"; }
+    }
+
+    public static void main(String[] args)
+    {
+        try {
+            Test6663854 t = new Test6663854();
+            try { t.test(); }
+            catch(Throwable e) { }
+            try { System.out.println(t); }
+            catch(Throwable e) { }
+        } catch (Throwable e) { }
+    }
+
+    private void test()
+    {
+        if ((true & (false ? !false : true) || var_107 ? (var_105 <<= Test6663854_Class_5.var_65) / (Test6663854_Class_0.var_5 = var_105) : 2509076152709535744L) >= (true ? new Test6663854_Class_8().var_93 : (Test6663854_Class_3.var_20 = Test6663854_Class_3.var_23)))
+        {
+            (true ? (new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23] : (Test6663854_Class_7.var_66 = new Test6663854_Class_6())).func_0();
+            (var_107 ? (new Test6663854_Class_4().var_41 = new Test6663854_Class_3()) : (Test6663854_Class_3)(new Test6663854_Class_3().var_18 = new Test6663854_Class_8())).var_18 = (new Test6663854_Class_4[new Test6663854_Class_4().var_43 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[Test6663854_Class_3.var_23];
+            {
+                ++var_106;
+                ((new Test6663854_Class_5().func_0() ? (Test6663854_Class_3.var_24 ^= true) : !false) ? (Test6663854_Class_7)new Test6663854_Class_5() : (Test6663854_Class_7)((Test6663854_Class_6.var_82 = new Test6663854_Class_3()).var_18 = (Test6663854_Class_6.var_80 = new Test6663854_Class_4()))).var_89 -= Test6663854_Class_3.var_23;
+            }
+            var_105 *= 4.59906108270682E307;
+            {
+                Test6663854_Class_0.var_4 = ((Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = new Test6663854_Class_4()))).var_43 = (Test6663854_Class_0.var_4 = false ? (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) : Test6663854_Class_3.var_23));
+            }
+            long var_113 = 0L;
+            var_106 %= (Test6663854_Class_7.var_88 = 'i');
+            for (short var_114 = ((Test6663854_Class_8)(new Test6663854_Interface_1[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))])[Test6663854_Class_3.var_23]).var_94; var_113 < 4 && false; "dmmntw".length())
+            {
+                var_114++;
+                var_113++;
+                Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24;
+                new String("kprvouugy");
+            }
+            {
+                new Test6663854_Class_8().var_94 /= (long)5.719961906225282E307;
+            }
+            double var_115 = 0;
+            Test6663854_Class_3.var_24 |= var_107;
+            do
+            {
+                Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 |= !Test6663854_Class_3.var_24 && var_107);
+                var_115++;
+                var_106++;
+            } while (var_115 < 29 && (var_107 = (Test6663854_Class_3.var_24 |= Test6663854_Class_3.var_24)));
+            Test6663854_Class_7.var_66 = new Test6663854_Class_7();
+            Test6663854_Class_3.var_20 = (false ? (Test6663854_Class_6.var_80 = new Test6663854_Class_4()) : new Test6663854_Class_4()).var_42;
+        }
+        else
+        {
+            (((new Test6663854_Class_3[Test6663854_Class_3.var_23])[new Test6663854_Class_6().var_78]).var_22 = (new Test6663854_Class_3().var_22 = (new Test6663854_Class_3().var_22 = new Test6663854_Class_0()))).var_8 >>>= (var_106 &= new Test6663854_Class_0().var_8 << Test6663854_Class_7.var_65);
+        }
+        Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = new Test6663854_Class_4()));
+        {
+            Test6663854_Class_8 var_116;
+            (!true | (Test6663854_Class_3.var_24 &= true) ? new Test6663854_Class_7() : new Test6663854_Class_7()).var_89 /= Test6663854_Class_7.var_88--;
+            Test6663854_Class_6.var_81 &= ((new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_78;
+        }
+        if (true ? var_107 : (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 |= false)))
+        {
+            Test6663854_Class_3.var_24 |= (Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 ^= (Test6663854_Class_3.var_24 &= !true)));
+            Test6663854_Class_7.var_66 = (Test6663854_Class_7)new Test6663854_Class_5();
+            Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)));
+            {
+                Test6663854_Class_7.var_88++;
+                float var_117 = 0F;
+                final long var_118 = 1388589135930756096L;
+                for (var_106++; ((Test6663854_Class_3.var_24 &= false) && (Test6663854_Class_3.var_24 |= true)) ^ true && (var_117 < 1 && Test6663854_Class_3.var_24); new Test6663854_Class_0().var_8 += !false || (new float[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] <= Test6663854_Class_3.var_23 || Test6663854_Class_3.var_24 ? ((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78 : Test6663854_Class_3.var_23)
+                {
+                    Test6663854_Class_6.var_82 = (Test6663854_Class_7.var_67 = new Test6663854_Class_3());
+                    var_117++;
+                    Test6663854_Class_5.var_66 = Test6663854_Class_3.var_24 & !Test6663854_Class_3.var_24 ^ var_107 ^ new Test6663854_Class_0().var_8 == new Test6663854_Class_0().var_1 ? new Test6663854_Class_6() : new Test6663854_Class_6();
+                    (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_43 = (Test6663854_Class_0.var_4 = ((Test6663854_Class_6)(new Object[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_78);
+                }
+                if (false & ((var_107 = true) || ! ((Test6663854_Class_3.var_24 ^= true || !var_107) ? false : Test6663854_Class_3.var_24 ^ var_107) ? (var_107 = Test6663854_Class_3.var_24) && Test6663854_Class_3.var_24 : true))
+                {
+                    "yvjk".toString();
+                }
+                else
+                {
+                    Test6663854_Class_4 var_119 = Test6663854_Class_6.var_80 = ((var_107 = true) ? (Test6663854_Class_6.var_81 |= var_106) : var_118) < (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) ? (Test6663854_Class_4)(new Test6663854_Class_3().var_18 = new float[Test6663854_Class_3.var_23]) : (new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23];
+                }
+                (false | (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) >= var_106 ? new Test6663854_Class_3() : (Test6663854_Class_7.var_67 = new Test6663854_Class_3())).var_18 = ((false ? (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] : new Test6663854_Class_3()).var_22 = ((Test6663854_Class_7.var_67 = (Test6663854_Class_3)(new Test6663854_Class_3().var_18 = (Test6663854_Class_8)(new Test6663854_Class_8().var_96 = new Test6663854_Class_8()))).var_22 = ((Test6663854_Class_5.var_67 = new Test6663854_Class_3()).var_22 = new Test6663854_Class_0())));
+                short var_120;
+                (Test6663854_Class_6.var_80 = new Test6663854_Class_4()).var_41 = new Test6663854_Class_3();
+                ((new Test6663854_Class_8[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_96 = (Test6663854_Class_4.var_40 = !false & var_107 ? (Test6663854_Class_7)new Test6663854_Class_5() : new Test6663854_Class_7());
+            }
+            if ((Test6663854_Class_3.var_24 &= (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24)) || Test6663854_Class_3.var_24)
+            {
+                {
+                    var_106--;
+                    Test6663854_Class_6.var_81 -= 2.5265952E38F;
+                    Test6663854_Class_7.var_88++;
+                    Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]));
+                    Test6663854_Class_6.var_81++;
+                    (((new Test6663854_Class_7[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[(byte)(var_105 &= var_106)])[Test6663854_Class_3.var_23]).equals(((new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_18 = new Test6663854_Class_8());
+                }
+                ((((new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_41 = (Test6663854_Class_7.var_67 = (Test6663854_Class_7.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_18 = "mnxktbgv";
+                var_105++;
+                ((Test6663854_Class_3.var_24 &= Test6663854_Class_3.var_24) ? (new Test6663854_Class_3().var_22 = new Test6663854_Class_0()) : new Test6663854_Class_0()).var_7 = new Test6663854_Class_0().var_6;
+                var_105 = (var_105 >>>= Test6663854_Class_3.var_23);
+                ++var_105;
+                {
+                    Test6663854_Class_0.var_4 = ((Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_43 = ((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_78);
+                    ((Test6663854_Class_8)(new Object[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_96 = (Test6663854_Class_6.var_80 = (Test6663854_Class_4)(Test6663854_Class_5.var_66 = (new Test6663854_Class_6[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]));
+                }
+                if (2125632862 >= Test6663854_Class_5.var_65)
+                {
+                    "nfdjgd".toLowerCase();
+                    ((new Test6663854_Class_8[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]).var_96 = new Test6663854_Class_8();
+                    Test6663854_Interface_2 var_121;
+                    new Test6663854_Class_0().var_7 = Test6663854_Class_8.var_97;
+                    --var_105;
+                    --Test6663854_Class_7.var_88;
+                    ((new Test6663854_Class_0[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)])[((Test6663854_Class_6)(Test6663854_Class_4.var_40 = (Test6663854_Class_3)(new Object[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])).var_78]).var_7 = (((new Test6663854_Class_8[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_94 += (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23));
+                }
+                else
+                {
+                    --Test6663854_Class_6.var_81;
+                }
+                if (false)
+                {
+                    Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23;
+                }
+                else
+                {
+                    var_105--;
+                    (true | (Test6663854_Class_3.var_24 |= var_107) ? (Test6663854_Class_7)(new Test6663854_Class_5[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23] : (new Test6663854_Class_7[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]).var_89 *= 2.5396491E38F;
+                    var_107 = Test6663854_Class_3.var_24;
+                    var_105++;
+                }
+                Test6663854_Class_6.var_81--;
+                new Test6663854_Class_5();
+            }
+            else
+            {
+                Test6663854_Class_0 var_122;
+            }
+            var_107 = false;
+            (Test6663854_Class_3.var_24 ? new Test6663854_Class_7() : (Test6663854_Class_7)(new Test6663854_Class_3().var_18 = new Test6663854_Class_6())).var_89 *= (var_106 -= (new Test6663854_Class_3().var_22 = new Test6663854_Class_0()).var_6);
+            new Test6663854_Class_8().var_94 *= Test6663854_Class_7.var_88;
+            ((new String[new Test6663854_Class_6().var_78])[Test6663854_Class_3.var_23]).codePointAt(135817988);
+            final double var_123 = 7.395191963488875E307;
+            --var_105;
+            Test6663854_Class_7.var_88++;
+        }
+        else
+        {
+            (Test6663854_Class_6.var_80 = Test6663854_Class_3.var_24 ? (Test6663854_Class_6.var_80 = new Test6663854_Class_4()) : (Test6663854_Class_6.var_80 = new Test6663854_Class_4())).var_38 <<= (Test6663854_Class_7.var_88 <<= (new Test6663854_Class_4().var_43 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))) >>> Test6663854_Class_3.var_23);
+        }
+        int var_124 = 0;
+        Test6663854_Class_7 var_125;
+        float var_126 = 2.5216562E38F;
+        int var_127 = 0;
+        Test6663854_Class_7.var_66 = (Test6663854_Class_5.var_66 = (Test6663854_Class_4)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]);
+        while (var_127 < 1 && (Test6663854_Class_3.var_24 ? (var_107 |= var_107) : false))
+        {
+            short var_128;
+            var_127++;
+            var_125 = (var_125 = (var_125 = (var_125 = (Test6663854_Class_7)(new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])));
+            "nkv".indexOf("ptrepiu" + "aljmjttym", var_106 << (new byte[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]);
+        }
+        {
+            Test6663854_Class_7.var_66 = (Test6663854_Class_7.var_67 = (new Test6663854_Class_3[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]);
+        }
+        var_125 = (new Test6663854_Class_7[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23];
+        var_126 += var_106;
+        while (var_124 < 537 && true)
+        {
+            Test6663854_Class_7.var_88 %= var_105;
+            var_124++;
+            var_106++;
+            Test6663854_Class_5.var_66 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]));
+            final long var_129 = 3230407753980990464L;
+            new Test6663854_Class_8();
+            final Test6663854_Class_3 var_130 = (Test6663854_Class_3)((Test6663854_Class_3.var_24 |= !false) | (var_107 | !var_107) | (new Test6663854_Class_8().var_94++ >= 1015752753 | !true) ? (new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23] : (new Test6663854_Interface_1[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23]);
+            Test6663854_Class_5.var_66 = (Test6663854_Class_7.var_66 = (Test6663854_Class_7.var_66 = (Test6663854_Class_7.var_67 = var_130)));
+        }
+        Test6663854_Class_7.var_66 = var_126 >= (Test6663854_Class_3.var_24 || (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24) ? var_106 : var_126) ? new Test6663854_Class_6() : new Test6663854_Class_6();
+        var_107 &= true;
+        (new Test6663854_Class_8().var_96 = (var_125 = (var_125 = (var_125 = new Test6663854_Class_7())))).func_0();
+        float var_131 = 0F;
+        Test6663854_Class_3 var_132 = new Test6663854_Class_3();
+        do
+        {
+            long var_133;
+            var_131++;
+            Test6663854_Interface_2 var_134 = Test6663854_Class_7.var_66 = var_132;
+        } while ((Test6663854_Class_3.var_24 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23) == 1.2758309E38F) && (var_131 < 117 && ((new short[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)] == ((var_107 &= ! (Test6663854_Class_3.var_24 ^= false)) ^ ! !false ? new Test6663854_Class_0().var_6 : new Test6663854_Class_4().var_42)));
+        (var_107 ? var_132 : (Test6663854_Class_3)(Test6663854_Class_7.var_66 = var_132)).var_18 = (Test6663854_Class_0)((Test6663854_Class_5.var_67 = (Test6663854_Class_7.var_67 = (var_132 = var_132))).var_18 = ((new Test6663854_Class_8[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23))])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]);
+        long var_135 = 0L;
+        (((new Test6663854_Class_8[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = (byte)+ (Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23)]).var_96 = var_132;
+        for (((var_107 = ((new Test6663854_Class_0[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).equals(var_132.var_18 = (Test6663854_Class_8)(new Test6663854_Class_8().var_96 = var_132))) ? "oedsntb" : "ouspr").concat("t"); var_135 < 27; (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23]))).var_38 %= (double)func_0(Test6663854_Class_3.var_24 = false ? !var_107 && ! !Test6663854_Class_3.var_24 : Test6663854_Class_3.var_24 ^ ! (Test6663854_Class_3.var_24 = Test6663854_Class_3.var_24)))
+        {
+            Test6663854_Class_6.var_80 = (Test6663854_Class_4)(new Test6663854_Class_8().var_96 = new Test6663854_Class_8());
+            var_135++;
+            Test6663854_Class_3.var_24 &= !true;
+            new Test6663854_Class_0().var_8 += Test6663854_Class_7.var_65;
+        }
+        Test6663854_Class_3 var_136 = var_132;
+        if ((var_107 = ((Test6663854_Class_4)(Test6663854_Class_7.var_66 = (var_125 = (Test6663854_Class_7)(Test6663854_Class_7.var_66 = var_136)))).func_0() ^ true) && (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (Test6663854_Class_6.var_80 = (new Test6663854_Class_4[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]))).var_45 <= ((new Test6663854_Class_6[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23]).var_78)
+        {
+            var_126 %= ((var_107 = true) ? (var_105 *= 8272288534835139584L) : (var_105 |= var_105)) % new Test6663854_Class_7().var_89;
+            ((Test6663854_Class_3)(new Test6663854_Class_8().var_96 = (new Test6663854_Interface_1[Test6663854_Class_3.var_23])[Test6663854_Class_3.var_23])).var_18 = new Test6663854_Class_0();
+            var_105 <<= ++((Test6663854_Class_3.var_24 |= false) ? new Test6663854_Class_8() : (Test6663854_Class_8)(new Test6663854_Class_8().var_96 = new Test6663854_Class_4())).var_94 % (Test6663854_Class_0.var_2 - var_106);
+            Test6663854_Interface_2 var_137;
+            var_137 = new Test6663854_Class_4();
+            int var_138;
+        }
+        else
+        {
+            final Test6663854_Interface_2 var_139 = Test6663854_Class_4.var_40 = (var_136 = var_136);
+            new Test6663854_Class_8().var_93 -= new Test6663854_Class_6().var_78;
+            --((Test6663854_Class_3.var_24 ^= var_126 < Test6663854_Class_3.var_23 | !var_107) ? (new Test6663854_Class_8[Test6663854_Class_3.var_23][Test6663854_Class_3.var_23])[Test6663854_Class_0.var_4 = Test6663854_Class_3.var_23][new Test6663854_Class_6().var_78] : new Test6663854_Class_8()).var_93;
+            var_105 >>= ! (Test6663854_Class_3.var_24 = true) || ((Test6663854_Class_8)(! (Test6663854_Class_3.var_24 |= var_107) | (false ? Test6663854_Class_3.var_23 : new Test6663854_Class_6().var_78) != new Test6663854_Class_8().var_93 ? (Test6663854_Class_6.var_82 = var_136) : (new Test6663854_Class_8().var_96 = (var_132 = var_136)))).var_94 >= Test6663854_Class_6.var_81++ ? var_124 : '`';
+        }
+        var_126 /= var_105;
+        var_105 *= var_127;
+        var_107 ^= (var_107 = true);
+        {
+            Test6663854_Class_7.var_66 = (var_125 = (Test6663854_Class_7)(new Test6663854_Class_5[Test6663854_Class_3.var_23])[new Test6663854_Class_6().var_78]);
+        }
+        (var_136.var_22 = ((var_136 = var_132).var_22 = new Test6663854_Class_0())).var_7 = ((!false ? var_132 : (Test6663854_Class_7.var_67 = var_132)).var_22 = (((Test6663854_Class_3)(var_136.var_18 = var_136)).var_22 = (Test6663854_Class_0)(var_132.var_18 = "sgybwy"))).var_6;
+        ((Test6663854_Class_3.var_20 = var_105--) >= ~Test6663854_Class_3.var_23 ? new String() : "lgcfkbsw").replace(new Test6663854_Class_0().var_8 |= 't', false ? (Test6663854_Class_7.var_88 -= var_105) : 'q');
+        Test6663854_Class_7.var_88 <<= Test6663854_Class_7.var_88;
+    }
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Test6663854.var_105 = "; result += Printer.print(var_105);
+        result += "\n";
+        result += "Test6663854.var_107 = "; result += Printer.print(var_107);
+        result += "\n";
+        result += "Test6663854.var_106 = "; result += Printer.print(var_106);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+    static class Printer
+    {
+        public static String print(boolean arg) { return String.valueOf(arg); }
+        public static String print(byte arg)    { return String.valueOf(arg); }
+        public static String print(short arg)   { return String.valueOf(arg); }
+        public static String print(char arg)    { return String.valueOf((int)arg); }
+        public static String print(int arg)     { return String.valueOf(arg); }
+        public static String print(long arg)    { return String.valueOf(arg); }
+        public static String print(float arg)   { return String.valueOf(arg); }
+        public static String print(double arg)  { return String.valueOf(arg); }
+
+
+        public static String print(Object arg)
+        {
+            return print_r(new java.util.Stack(), arg);
+        }
+
+        private static String print_r(java.util.Stack visitedObjects, Object arg)
+        {
+            String result = "";
+            if (arg == null)
+                result += "null";
+            else
+            if (arg.getClass().isArray())
+            {
+                for (int i = 0; i < visitedObjects.size(); i++)
+                    if (visitedObjects.elementAt(i) == arg) return "<recursive>";
+
+                visitedObjects.push(arg);
+
+                final String delimiter = ", ";
+                result += "[";
+
+                if (arg instanceof Object[])
+                {
+                    Object[] array = (Object[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print_r(visitedObjects, array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof boolean[])
+                {
+                    boolean[] array = (boolean[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof byte[])
+                {
+                    byte[] array = (byte[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof short[])
+                {
+                    short[] array = (short[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof char[])
+                {
+                    char[] array = (char[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof int[])
+                {
+                     int[] array = (int[]) arg;
+                     for (int i = 0; i < array.length; i++)
+                     {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                     }
+                }
+                else
+                if (arg instanceof long[])
+                {
+                    long[] array = (long[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof float[])
+                {
+                    float[] array = (float[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof double[])
+                {
+                    double[] array = (double[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+
+                result += "]";
+                visitedObjects.pop();
+
+            } else
+            {
+                result += arg.toString();
+            }
+
+            return result;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6892265/Test.java	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6892265
+ * @summary System.arraycopy unable to reference elements beyond Integer.MAX_VALUE bytes
+ *
+ * @run main/othervm Test
+ */
+
+public class Test {
+  static  final int NCOPY = 1;
+  static  final int OVERFLOW = 1;
+  static  int[] src2 = new int[NCOPY];
+  static  int[] dst2;
+
+  static void test() {
+    int N;
+    int SIZE;
+
+    N = Integer.MAX_VALUE/4 + OVERFLOW;
+    System.arraycopy(src2, 0, dst2, N, NCOPY);
+    System.arraycopy(dst2, N, src2, 0, NCOPY);
+  }
+
+  public static void main(String[] args) {
+    try {
+      dst2 = new int[NCOPY + Integer.MAX_VALUE/4 + OVERFLOW];
+    } catch (OutOfMemoryError e) {
+       System.exit(95); // Not enough memory
+    }
+    System.out.println("warmup");
+    for (int i=0; i <11000; i++) {
+      test();
+    }
+    System.out.println("start");
+    for (int i=0; i <1000; i++) {
+      test();
+    }
+    System.out.println("finish");
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6930043/Test6930043.java	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6930043
+ * @summary C2: SIGSEGV in javasoft.sqe.tests.lang.arr017.arr01702.arr01702.loop_forw(II)I
+ *
+ * @run main Test6930043
+ */
+
+import java.io.PrintStream;
+
+public class Test6930043 {
+    int[] a;
+    int idx;
+
+    public int loop_back(int i, int i_0_) {
+        int i_1_ = 0;
+        int[] is = a;
+        if (is == null) return 0;
+        for (int i_2_ = i; i_2_ >= i_0_; i_2_--)
+            i_1_ += is[idx = i_2_];
+        return i_1_;
+    }
+
+    public int loop_forw(int start, int end) {
+        int result = 0;
+        int[] is = a;
+        if (is == null) return 0;
+        for (int index = start; index < end; index++)
+            result += is[index];
+            // result += is[idx = index];
+        return result;
+    }
+
+    public static void main(String[] strings) {
+        Test6930043 var_Test6930043 = new Test6930043();
+        var_Test6930043.a = new int[1000000];
+        var_Test6930043.loop_forw(10, 999990);
+        var_Test6930043.loop_forw(10, 999990);
+        for (int i = 0; i < 3; i++) {
+            try {
+                if (var_Test6930043.loop_forw(-1, 999990) != 0) throw new InternalError();
+            } catch (ArrayIndexOutOfBoundsException e) { }
+        }
+        var_Test6930043.loop_back(999990, 10);
+        var_Test6930043.loop_back(999990, 10);
+        for (int i = 0; i < 3; i++) {
+            try {
+                if (var_Test6930043.loop_back(999990, -1) != 0) throw new InternalError();
+            } catch (ArrayIndexOutOfBoundsException e) { }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6932496/Test6932496.java	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6932496
+ * @summary incorrect deopt of jsr subroutine on 64 bit c1
+ *
+ * @compile -source 1.5 -target 1.5 -XDjsrlimit=0 Test6932496.java
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6932496.m Test6932496
+ */
+
+public class Test6932496 {
+    static class A {
+        volatile boolean flag = false;
+    }
+
+    static void m() {
+        try {
+        } finally {
+            A a = new A();
+            a.flag = true;
+        }
+    }
+
+
+    static public void main(String[] args) {
+        m();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6935535/Test.java	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6935535
+ * @summary String.indexOf() returns incorrect result on x86 with SSE4.2
+ *
+ * @run main/othervm -Xcomp Test
+ */
+
+public class Test {
+
+  static int IndexOfTest(String str) {
+    return str.indexOf("1111111111111xx1x");
+  }
+
+  public static void main(String args[]) {
+    String str = "1111111111111xx1111111111111xx1x";
+    str = str.substring(0, 31);
+    int idx = IndexOfTest(str);
+    System.out.println("IndexOf(" + "1111111111111xx1x" + ") = " + idx + " in " + str);
+    if (idx != -1) {
+      System.exit(97);
+    }
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6929067/T.java	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,12 @@
+public class T
+{
+  public static boolean foo(boolean bar)
+  {
+    return bar;
+  }
+
+  public static void printIt()
+  {
+    System.out.println("Hello");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/6929067/Test6929067.sh	Mon Apr 19 20:41:10 2010 -0700
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+##
+## @test Test6929067.sh
+## @bug 6929067
+## @summary Stack guard pages should be removed when thread is detached
+## @run shell Test6929067.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+t