changeset 7992:42ed82f1c067

Merge
author lana
date Wed, 19 Jan 2011 19:00:30 -0800
parents 96cdf8806d96 f1df06807698
children 8778b8786a81 059b8737ff55
files jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.html jdk/test/java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.java jdk/test/javax/swing/SwingWorker/6480289/bug6480289.java langtools/test/tools/javac/meth/InvokeDyn.java langtools/test/tools/javac/meth/InvokeDynTrans.java
diffstat 199 files changed, 7146 insertions(+), 2410 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Jan 17 13:29:12 2011 +0530
+++ b/.hgtags	Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
 0ce0a2c3a6926677dc507839a820ab6625541e5a jdk7-b121
 6f09ea1c034f087916d2a8cf0d22be768400118f jdk7-b122
 142129d8599d1f56b29387e7f9a5fad53b6d61df jdk7-b123
+aa894c225b1a517b665ac2a58295217ea2245134 jdk7-b124
+f658ec2730fa29323c36d23c27e54c7219ef5e16 jdk7-b125
--- a/.hgtags-top-repo	Mon Jan 17 13:29:12 2011 +0530
+++ b/.hgtags-top-repo	Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
 2c2d4f88637b488014c37e1a2eb401f68bca8838 jdk7-b121
 f1591eed71f64f6eba79fb7426f5616cc4dfea73 jdk7-b122
 ed6950da30cf1e8904b4bdb034d471647942271f jdk7-b123
+024a6755895bf91b5a3c98984c89ee018efbf538 jdk7-b124
+5c4df7e992775c102f08e9f1c0a124b324641b70 jdk7-b125
--- a/corba/.hgtags	Mon Jan 17 13:29:12 2011 +0530
+++ b/corba/.hgtags	Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
 2cc9f32992101732b23730b737740e64ebc5fa89 jdk7-b121
 1523a060032c8a5b7840198da8911abeff88118f jdk7-b122
 a230c142628cea22475ab9dc5cd544266ddf2466 jdk7-b123
+f90b3e014e831eb4f32ef035a1dad2b8ba87949f jdk7-b124
+1ce58c72b7892cb813eb920276c7e7f17a1b79fe jdk7-b125
--- a/hotspot/.hgtags	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/.hgtags	Wed Jan 19 19:00:30 2011 -0800
@@ -138,3 +138,6 @@
 5484e7c53fa7da5e869902437ee08a9ae10c1c69 hs20-b03
 9669f9b284108a9ee0a0ccbe215c37a130c9dcf5 jdk7-b123
 9669f9b284108a9ee0a0ccbe215c37a130c9dcf5 hs20-b04
+0a8e0d4345b37b71ec49dda08ee03b68c4f1b592 jdk7-b124
+0a8e0d4345b37b71ec49dda08ee03b68c4f1b592 hs20-b05
+e24ab3fa6aafad3efabbe7dba9918c5f461a20b1 jdk7-b125
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -99,15 +99,8 @@
     long typeEntrySizeOffset;
     long typeEntryArrayStride;
 
-    typeEntryTypeNameOffset       = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
-    typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
-    typeEntryIsOopTypeOffset      = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
-    typeEntryIsIntegerTypeOffset  = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
-    typeEntryIsUnsignedOffset     = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
-    typeEntrySizeOffset           = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
-    typeEntryArrayStride          = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
-
-    // Fetch the address of the VMTypeEntry*
+    // Fetch the address of the VMTypeEntry*. We get this symbol first
+    // and try to use it to make sure that symbol lookup is working.
     Address entryAddr = lookupInProcess("gHotSpotVMTypes");
     //    System.err.println("gHotSpotVMTypes address = " + entryAddr);
     // Dereference this once to get the pointer to the first VMTypeEntry
@@ -118,6 +111,14 @@
       throw new RuntimeException("gHotSpotVMTypes was not initialized properly in the remote process; can not continue");
     }
 
+    typeEntryTypeNameOffset       = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
+    typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
+    typeEntryIsOopTypeOffset      = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
+    typeEntryIsIntegerTypeOffset  = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
+    typeEntryIsUnsignedOffset     = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
+    typeEntrySizeOffset           = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
+    typeEntryArrayStride          = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
+
     // Start iterating down it until we find an entry with no name
     Address typeNameAddr = null;
     do {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,10 +122,14 @@
       private MemoizedObject[] sectionHeaders;
       private MemoizedObject[] symbols;
 
+      // Init stringTable at decl time since other fields init'ed in the
+      // constructor need the String Table.
       private MemoizedObject stringTable = new MemoizedObject() {
           public Object computeValue() {
+            // the String Table follows the Symbol Table
             int ptr = getPointerToSymbolTable();
             if (ptr == 0) {
+              // no Symbol Table so no String Table
               return new StringTable(0);
             } else {
               return new StringTable(ptr + SYMBOL_SIZE * getNumberOfSymbols());
@@ -140,6 +144,8 @@
         timeDateStamp = readInt();
         pointerToSymbolTable = readInt();
         numberOfSymbols = readInt();
+        // String Table can be accessed at this point because
+        // pointerToSymbolTable and numberOfSymbols fields are set.
         sizeOfOptionalHeader = readShort();
         characteristics = readShort();
 
@@ -222,6 +228,8 @@
         private MemoizedObject windowsSpecificFields;
         private MemoizedObject dataDirectories;
 
+        // We use an offset of 2 because OptionalHeaderStandardFieldsImpl doesn't
+        // include the 'magic' field.
         private static final int STANDARD_FIELDS_OFFSET = 2;
         private static final int PE32_WINDOWS_SPECIFIC_FIELDS_OFFSET = 28;
         private static final int PE32_DATA_DIRECTORIES_OFFSET = 96;
@@ -288,7 +296,7 @@
         private int sizeOfUninitializedData;
         private int addressOfEntryPoint;
         private int baseOfCode;
-        private int baseOfData;
+        private int baseOfData;  // only set in PE32
 
         OptionalHeaderStandardFieldsImpl(int offset,
                                          boolean isPE32Plus) {
@@ -301,7 +309,8 @@
           sizeOfUninitializedData = readInt();
           addressOfEntryPoint = readInt();
           baseOfCode = readInt();
-          if (isPE32Plus) {
+          if (!isPE32Plus) {
+            // only available in PE32
             baseOfData = readInt();
           }
         }
@@ -433,7 +442,10 @@
                 if (dir.getRVA() == 0 || dir.getSize() == 0) {
                   return null;
                 }
-                return new ExportDirectoryTableImpl(rvaToFileOffset(dir.getRVA()), dir.getSize());
+                // ExportDirectoryTableImpl needs both the RVA and the
+                // RVA converted to a file offset.
+                return new
+                    ExportDirectoryTableImpl(dir.getRVA(), dir.getSize());
               }
             };
 
@@ -526,6 +538,7 @@
       }
 
       class ExportDirectoryTableImpl implements ExportDirectoryTable {
+        private int exportDataDirRVA;
         private int offset;
         private int size;
 
@@ -548,8 +561,9 @@
         private MemoizedObject exportOrdinalTable;
         private MemoizedObject exportAddressTable;
 
-        ExportDirectoryTableImpl(int offset, int size) {
-          this.offset = offset;
+        ExportDirectoryTableImpl(int exportDataDirRVA, int size) {
+          this.exportDataDirRVA = exportDataDirRVA;
+          offset = rvaToFileOffset(exportDataDirRVA);
           this.size   = size;
           seek(offset);
           exportFlags = readInt();
@@ -595,6 +609,7 @@
 
           exportOrdinalTable = new MemoizedObject() {
               public Object computeValue() {
+                // number of ordinals is same as the number of name pointers
                 short[] ordinals = new short[getNumberOfNamePointers()];
                 seek(rvaToFileOffset(getOrdinalTableRVA()));
                 for (int i = 0; i < ordinals.length; i++) {
@@ -608,14 +623,18 @@
               public Object computeValue() {
                 int[] addresses = new int[getNumberOfAddressTableEntries()];
                 seek(rvaToFileOffset(getExportAddressTableRVA()));
-                // Must make two passes to avoid rvaToFileOffset
-                // destroying seek() position
+                // The Export Address Table values are a union of two
+                // possible values:
+                //   Export RVA - The address of the exported symbol when
+                //       loaded into memory, relative to the image base.
+                //       This value doesn't get converted into a file offset.
+                //   Forwarder RVA - The pointer to a null-terminated ASCII
+                //       string in the export section. This value gets
+                //       converted into a file offset because we have to
+                //       fetch the string.
                 for (int i = 0; i < addresses.length; i++) {
                   addresses[i] = readInt();
                 }
-                for (int i = 0; i < addresses.length; i++) {
-                  addresses[i] = rvaToFileOffset(addresses[i]);
-                }
                 return addresses;
               }
             };
@@ -648,11 +667,12 @@
 
         public boolean isExportAddressForwarder(short ordinal) {
           int addr = getExportAddress(ordinal);
-          return ((offset <= addr) && (addr < (offset + size)));
+          return ((exportDataDirRVA <= addr) &&
+              (addr < (exportDataDirRVA + size)));
         }
 
         public String getExportAddressForwarder(short ordinal) {
-          seek(getExportAddress(ordinal));
+          seek(rvaToFileOffset(getExportAddress(ordinal)));
           return readCString();
         }
 
@@ -3371,10 +3391,17 @@
               throw new COFFException(e);
             }
             // Look up in string table
+            // FIXME: this index value is assumed to be in the valid range
             name = getStringTable().get(index);
           } else {
             try {
-              name = new String(tmpName, US_ASCII);
+              int length = 0;
+              // find last non-NULL
+              for (; length < tmpName.length && tmpName[length] != '\0';) {
+                length++;
+              }
+              // don't include NULL chars in returned name String
+              name = new String(tmpName, 0, length, US_ASCII);
             } catch (UnsupportedEncodingException e) {
               throw new COFFException(e);
             }
@@ -3487,6 +3514,7 @@
                                 tmpName[5] << 16 |
                                 tmpName[6] <<  8 |
                                 tmpName[7]);
+            // FIXME: stringOffset is assumed to be in the valid range
             name = getStringTable().getAtOffset(stringOffset);
           }
 
@@ -3698,12 +3726,13 @@
 
         StringTable(int offset) {
           if (offset == 0) {
+            // no String Table
             strings = new COFFString[0];
             return;
           }
 
           seek(offset);
-          int length = readInt();
+          int length = readInt();  // length includes itself
           byte[] data = new byte[length - 4];
           int numBytesRead = readBytes(data);
           if (numBytesRead != data.length) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,35 +37,48 @@
 
     String filename = args[0];
     COFFFile file   = COFFFileParser.getParser().parse(filename);
-    ExportDirectoryTable exports =
-      file.getHeader().
-        getOptionalHeader().
-          getDataDirectories().
-            getExportDirectoryTable();
+
+    // get common point for both things we want to dump
+    OptionalHeaderDataDirectories dataDirs = file.getHeader().getOptionalHeader().
+        getDataDirectories();
+
+    // dump the header data directory for the Export Table:
+    DataDirectory dir = dataDirs.getExportTable();
+    System.out.println("Export table: RVA = " + dir.getRVA() + "/0x" +
+        Integer.toHexString(dir.getRVA()) + ", size = " + dir.getSize() + "/0x" +
+        Integer.toHexString(dir.getSize()));
+
+    System.out.println(file.getHeader().getNumberOfSections() + " sections in file");
+    for (int i = 1; i <= file.getHeader().getNumberOfSections(); i++) {
+      SectionHeader sec = file.getHeader().getSectionHeader(i);
+      System.out.println("  Section " + i + ":");
+      System.out.println("    Name = '" + sec.getName() + "'");
+      System.out.println("    VirtualSize = " + sec.getSize() + "/0x" +
+          Integer.toHexString(sec.getSize()));
+      System.out.println("    VirtualAddress = " + sec.getVirtualAddress() + "/0x" +
+          Integer.toHexString(sec.getVirtualAddress()));
+      System.out.println("    SizeOfRawData = " + sec.getSizeOfRawData() + "/0x" +
+          Integer.toHexString(sec.getSizeOfRawData()));
+      System.out.println("    PointerToRawData = " + sec.getPointerToRawData() + "/0x" +
+          Integer.toHexString(sec.getPointerToRawData()));
+    }
+
+    ExportDirectoryTable exports = dataDirs.getExportDirectoryTable();
     if (exports == null) {
       System.out.println("No exports found.");
     } else {
-      System.out.println(file.getHeader().getNumberOfSections() + " sections in file");
-      for (int i = 0; i < file.getHeader().getNumberOfSections(); i++) {
-        System.out.println("  Section " + i + ": " + file.getHeader().getSectionHeader(1 + i).getName());
-      }
-
-      DataDirectory dir = file.getHeader().getOptionalHeader().getDataDirectories().getExportTable();
-      System.out.println("Export table: RVA = 0x" + Integer.toHexString(dir.getRVA()) +
-                         ", size = 0x" + Integer.toHexString(dir.getSize()));
-
       System.out.println("DLL name: " + exports.getDLLName());
       System.out.println("Time/date stamp 0x" + Integer.toHexString(exports.getTimeDateStamp()));
       System.out.println("Major version 0x" + Integer.toHexString(exports.getMajorVersion() & 0xFFFF));
       System.out.println("Minor version 0x" + Integer.toHexString(exports.getMinorVersion() & 0xFFFF));
-      System.out.println(exports.getNumberOfNamePointers() + " functions found");
+      System.out.println(exports.getNumberOfNamePointers() + " exports found");
       for (int i = 0; i < exports.getNumberOfNamePointers(); i++) {
-        System.out.println("  0x" +
-                           Integer.toHexString(exports.getExportAddress(exports.getExportOrdinal(i))) +
-                           "  " +
-                           (exports.isExportAddressForwarder(exports.getExportOrdinal(i))  ?
-                            ("Forwarded to " + exports.getExportAddressForwarder(exports.getExportOrdinal(i))) :
-                            exports.getExportName(i)));
+        short ordinal = exports.getExportOrdinal(i);
+        System.out.print("[" + i + "] '" + exports.getExportName(i) + "': [" +
+            ordinal + "] = 0x" + Integer.toHexString(exports.getExportAddress(ordinal)));
+        System.out.println(exports.isExportAddressForwarder(ordinal)
+            ? "  Forwarded to '" + exports.getExportAddressForwarder(ordinal) + "'"
+            : "");
       }
     }
   }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,8 +42,8 @@
       COFFHeader header = file.getHeader();
       int numSections = header.getNumberOfSections();
       System.out.println(numSections + " sections detected.");
-      for (int i = 0; i < numSections; i++) {
-        SectionHeader secHeader = header.getSectionHeader(1 + i);
+      for (int i = 1; i <= numSections; i++) {
+        SectionHeader secHeader = header.getSectionHeader(i);
         System.out.println(secHeader.getName());
       }
 
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -506,7 +506,6 @@
     throw new DebuggerException("Unimplemented");
   }
 
-  private static String  DTFWHome;
   private static String  imagePath;
   private static String  symbolPath;
   private static boolean useNativeLookup;
@@ -514,81 +513,143 @@
     static {
 
      /*
-      * sawindbg.dll depends on dbgeng.dll which
-      * itself depends on dbghelp.dll. dbgeng.dll and dbghelp.dll.
-      * On systems newer than Windows 2000, these two .dlls are
-      * in the standard system directory so we will find them there.
-      * On Windows 2000 and earlier, these files do not exist.
-      * The user must download Debugging Tools For Windows (DTFW)
-      * and install it in order to use SA.
+      * sawindbg.dll depends on dbgeng.dll which itself depends on
+      * dbghelp.dll. We have to make sure that the dbgeng.dll and
+      * dbghelp.dll that we load are compatible with each other. We
+      * load both of those libraries from the same directory based
+      * on the theory that co-located libraries are compatible.
+      *
+      * On Windows 2000 and earlier, dbgeng.dll and dbghelp.dll were
+      * not included as part of the standard system directory. On
+      * systems newer than Windows 2000, dbgeng.dll and dbghelp.dll
+      * are included in the standard system directory. However, the
+      * versions included in the standard system directory may not
+      * be able to handle symbol information for the newer compilers.
+      *
+      * We search for and explicitly load the libraries using the
+      * following directory search order:
       *
-      * We have to make sure we use the two files from the same directory
-      * in case there are more than one copy on the system because
-      * one version of dbgeng.dll might not be compatible with a
-      * different version of dbghelp.dll.
-      * We first look for them in the directory pointed at by
-      * env. var. DEBUGGINGTOOLSFORWINDOWS, next in the default
-      * installation dir for DTFW, and lastly in the standard
-      * system directory.  We expect that that we will find
-      * them in the standard system directory on all systems
-      * newer than Windows 2000.
+      * - java.home/bin (same as $JAVA_HOME/jre/bin)
+      * - dir named by DEBUGGINGTOOLSFORWINDOWS environment variable
+      * - various "Debugging Tools For Windows" program directories
+      * - the system directory ($SYSROOT/system32)
+      *
+      * If SA is invoked with -Dsun.jvm.hotspot.loadLibrary.DEBUG=1,
+      * then debug messages about library loading are printed to
+      * System.err.
       */
-    String dirName = null;
-    DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS");
 
-    if (DTFWHome == null) {
-      // See if we have the files in the default location.
-      String sysRoot = System.getenv("SYSTEMROOT");
-      DTFWHome = sysRoot + File.separator +
-          ".." + File.separator + "Program Files" +
-          File.separator + "Debugging Tools For Windows";
-    }
+    String dbgengPath   = null;
+    String dbghelpPath  = null;
+    String sawindbgPath = null;
+    List   searchList   = new ArrayList();
+
+    boolean loadLibraryDEBUG =
+        System.getProperty("sun.jvm.hotspot.loadLibrary.DEBUG") != null;
 
     {
-      String dbghelp = DTFWHome + File.separator + "dbghelp.dll";
-      String dbgeng = DTFWHome + File.separator + "dbgeng.dll";
-      File fhelp = new File(dbghelp);
-      File feng = new File(dbgeng);
-      if (fhelp.exists() && feng.exists()) {
-        // found both, we are happy.
-        // NOTE: The order of loads is important! If we load dbgeng.dll
-        // first, then the dependency - dbghelp.dll - will be loaded
-        // from usual DLL search thereby defeating the purpose!
-        System.load(dbghelp);
-        System.load(dbgeng);
-      } else if (! fhelp.exists() && ! feng.exists()) {
-        // neither exist. We will ignore this dir and assume
-        // they are in the system dir.
-        DTFWHome = null;
-      } else {
-        // one exists but not the other
-        //System.err.println("Error: Both files dbghelp.dll and dbgeng.dll "
-        //                   "must exist in directory " + DTFWHome);
-        throw new UnsatisfiedLinkError("Both files dbghelp.dll and " +
-                                       "dbgeng.dll must exist in " +
-                                       "directory " + DTFWHome);
+      // First place to search is co-located with sawindbg.dll in
+      // $JAVA_HOME/jre/bin (java.home property is set to $JAVA_HOME/jre):
+      searchList.add(System.getProperty("java.home") + File.separator + "bin");
+      sawindbgPath = (String) searchList.get(0) + File.separator +
+          "sawindbg.dll";
+
+      // second place to search is specified by an environment variable:
+      String DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS");
+      if (DTFWHome != null) {
+        searchList.add(DTFWHome);
       }
-    }
-    if (DTFWHome == null) {
-      // The files better be in the system dir.
-      String sysDir = System.getenv("SYSTEMROOT") +
-          File.separator + "system32";
 
-      File feng = new File(sysDir + File.separator + "dbgeng.dll");
-      if (!feng.exists()) {
-        throw new UnsatisfiedLinkError("File dbgeng.dll does not exist in " +
-                                        sysDir + ".  Please search microsoft.com " +
-                                       "for Debugging Tools For Windows, and " +
-                                       "either download it to the default " +
-                                       "location, or download it to a custom " +
-                                       "location and set environment variable " +
-                                       "   DEBUGGINGTOOLSFORWINDOWS  "  +
-                                       "to the pathname of that location.");
-      }
+      // The third place to search is the install directory for the
+      // "Debugging Tools For Windows" package; so far there are three
+      // name variations that we know of:
+      String sysRoot = System.getenv("SYSTEMROOT");
+      DTFWHome = sysRoot + File.separator + ".." + File.separator +
+          "Program Files" + File.separator + "Debugging Tools For Windows";
+      searchList.add(DTFWHome);
+      searchList.add(DTFWHome + " (x86)");
+      searchList.add(DTFWHome + " (x64)");
+
+      // The last place to search is the system directory:
+      searchList.add(sysRoot + File.separator + "system32");
     }
 
+    for (int i = 0; i < searchList.size(); i++) {
+      File dir = new File((String) searchList.get(i));
+      if (!dir.exists()) {
+        if (loadLibraryDEBUG) {
+          System.err.println("DEBUG: '" + searchList.get(i) +
+              "': directory does not exist.");
+        }
+        // this search directory doesn't exist so skip it
+        continue;
+      }
+
+      dbgengPath = (String) searchList.get(i) + File.separator + "dbgeng.dll";
+      dbghelpPath = (String) searchList.get(i) + File.separator + "dbghelp.dll";
+
+      File feng = new File(dbgengPath);
+      File fhelp = new File(dbghelpPath);
+      if (feng.exists() && fhelp.exists()) {
+        // both files exist so we have a match
+        break;
+      }
+
+      // At least one of the files does not exist; no warning if both
+      // don't exist. If just one doesn't exist then we don't check
+      // loadLibraryDEBUG because we have a mis-configured system.
+      if (feng.exists()) {
+        System.err.println("WARNING: found '" + dbgengPath +
+            "' but did not find '" + dbghelpPath + "'; ignoring '" +
+            dbgengPath + "'.");
+      } else if (fhelp.exists()) {
+        System.err.println("WARNING: found '" + dbghelpPath +
+            "' but did not find '" + dbgengPath + "'; ignoring '" +
+            dbghelpPath + "'.");
+      } else if (loadLibraryDEBUG) {
+        System.err.println("DEBUG: searched '" + searchList.get(i) +
+          "': dbgeng.dll and dbghelp.dll were not found.");
+      }
+      dbgengPath = null;
+      dbghelpPath = null;
+    }
+
+    if (dbgengPath == null || dbghelpPath == null) {
+      // at least one of the files wasn't found anywhere we searched
+      String mesg = null;
+
+      if (dbgengPath == null && dbghelpPath == null) {
+        mesg = "dbgeng.dll and dbghelp.dll cannot be found. ";
+      } else if (dbgengPath == null) {
+        mesg = "dbgeng.dll cannot be found (dbghelp.dll was found). ";
+      } else {
+        mesg = "dbghelp.dll cannot be found (dbgeng.dll was found). ";
+      }
+      throw new UnsatisfiedLinkError(mesg +
+          "Please search microsoft.com for 'Debugging Tools For Windows', " +
+          "and either download it to the default location, or download it " +
+          "to a custom location and set environment variable " +
+          "'DEBUGGINGTOOLSFORWINDOWS' to the pathname of that location.");
+    }
+
+    // NOTE: The order of loads is important! If we load dbgeng.dll
+    // first, then the dependency - dbghelp.dll - will be loaded
+    // from usual DLL search thereby defeating the purpose!
+    if (loadLibraryDEBUG) {
+      System.err.println("DEBUG: loading '" + dbghelpPath + "'.");
+    }
+    System.load(dbghelpPath);
+    if (loadLibraryDEBUG) {
+      System.err.println("DEBUG: loading '" + dbgengPath + "'.");
+    }
+    System.load(dbgengPath);
+
     // Now, load sawindbg.dll
-    System.loadLibrary("sawindbg");
+    if (loadLibraryDEBUG) {
+      System.err.println("DEBUG: loading '" + sawindbgPath + "'.");
+    }
+    System.load(sawindbgPath);
+
     // where do I find '.exe', '.dll' files?
     imagePath = System.getProperty("sun.jvm.hotspot.debugger.windbg.imagePath");
     if (imagePath == null) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Wed Jan 19 19:00:30 2011 -0800
@@ -30,6 +30,7 @@
 import sun.jvm.hotspot.asm.sparc.*;
 import sun.jvm.hotspot.asm.x86.*;
 import sun.jvm.hotspot.asm.ia64.*;
+import sun.jvm.hotspot.asm.amd64.*;
 import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.compiler.*;
 import sun.jvm.hotspot.debugger.*;
@@ -198,6 +199,8 @@
          cpuHelper = new SPARCHelper();
       } else if (cpu.equals("x86")) {
          cpuHelper = new X86Helper();
+      } else if (cpu.equals("amd64")) {
+         cpuHelper = new AMD64Helper();
       } else if (cpu.equals("ia64")) {
          cpuHelper = new IA64Helper();
       } else {
--- a/hotspot/make/hotspot_version	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/hotspot_version	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 # 
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,11 @@
 #
 
 # Don't put quotes (fail windows build).
-HOTSPOT_VM_COPYRIGHT=Copyright 2010
+HOTSPOT_VM_COPYRIGHT=Copyright 2011
 
 HS_MAJOR_VER=20
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=05
+HS_BUILD_NUMBER=06
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/make/jprt.properties	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/jprt.properties	Wed Jan 19 19:00:30 2011 -0800
@@ -150,6 +150,7 @@
 
 jprt.my.solaris.sparc.test.targets= \
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark, \
     ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese, \
     ${jprt.my.solaris.sparc}-fastdebug-c1-runThese_Xshare, \
@@ -168,6 +169,7 @@
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_G1, \
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParOldGC, \
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_default, \
+    ${jprt.my.solaris.sparc}-{product|fastdebug}-c2-jbb_default_tiered, \
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
     ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_CMS, \
@@ -176,6 +178,7 @@
 
 jprt.my.solaris.sparcv9.test.targets= \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \
     ${jprt.my.solaris.sparcv9}-product-c2-runThese, \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default, \
@@ -193,6 +196,7 @@
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_G1, \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParOldGC, \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default_tiered, \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \
     ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_CMS, \
@@ -201,6 +205,7 @@
 
 jprt.my.solaris.x64.test.targets= \
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-scimark, \
     ${jprt.my.solaris.x64}-product-c2-runThese, \
     ${jprt.my.solaris.x64}-product-c2-runThese_Xcomp, \
@@ -219,6 +224,7 @@
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default_tiered, \
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
     ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
@@ -227,6 +233,7 @@
 
 jprt.my.solaris.i586.test.targets= \
     ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.solaris.i586}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark, \
     ${jprt.my.solaris.i586}-product-{c1|c2}-runThese_Xcomp, \
     ${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp, \
@@ -253,6 +260,7 @@
     ${jprt.my.solaris.i586}-product-c1-GCOld_G1, \
     ${jprt.my.solaris.i586}-product-c1-GCOld_ParOldGC, \
     ${jprt.my.solaris.i586}-fastdebug-c2-jbb_default, \
+    ${jprt.my.solaris.i586}-fastdebug-c2-jbb_default_tiered, \
     ${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParallelGC, \
     ${jprt.my.solaris.i586}-fastdebug-c2-jbb_CMS, \
     ${jprt.my.solaris.i586}-fastdebug-c2-jbb_G1, \
@@ -260,6 +268,7 @@
 
 jprt.my.linux.i586.test.targets = \
     ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-scimark, \
     ${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \
     ${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \
@@ -279,6 +288,7 @@
     ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_G1, \
     ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParOldGC, \
     ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_default, \
+    ${jprt.my.linux.i586}-{product|fastdebug}-c2-jbb_default_tiered, \
     ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \
     ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \
     ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_G1, \
@@ -286,6 +296,7 @@
 
 jprt.my.linux.x64.test.targets = \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_default, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
@@ -302,12 +313,14 @@
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_G1, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default_tiered, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_G1, \
     ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParOldGC
 
 jprt.my.windows.i586.test.targets = \
     ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-scimark, \
     ${jprt.my.windows.i586}-product-{c1|c2}-runThese, \
     ${jprt.my.windows.i586}-product-{c1|c2}-runThese_Xcomp, \
@@ -327,6 +340,7 @@
     ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_G1, \
     ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParOldGC, \
     ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jbb_default, \
+    ${jprt.my.windows.i586}-{product|fastdebug}-c2-jbb_default_tiered, \
     ${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParallelGC, \
     ${jprt.my.windows.i586}-product-{c1|c2}-jbb_CMS, \
     ${jprt.my.windows.i586}-product-{c1|c2}-jbb_G1, \
@@ -334,6 +348,7 @@
 
 jprt.my.windows.x64.test.targets = \
     ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98_tiered, \
     ${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark, \
     ${jprt.my.windows.x64}-product-c2-runThese, \
     ${jprt.my.windows.x64}-product-c2-runThese_Xcomp, \
@@ -351,6 +366,7 @@
     ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_G1, \
     ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
     ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default, \
+    ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default_tiered, \
     ${jprt.my.windows.x64}-product-c2-jbb_CMS, \
     ${jprt.my.windows.x64}-product-c2-jbb_ParallelGC, \
     ${jprt.my.windows.x64}-product-c2-jbb_G1, \
--- a/hotspot/make/solaris/makefiles/buildtree.make	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/solaris/makefiles/buildtree.make	Wed Jan 19 19:00:30 2011 -0800
@@ -61,7 +61,7 @@
 QUIETLY$(MAKE_VERBOSE)	= @
 
 # For now, until the compiler is less wobbly:
-TESTFLAGS	= -Xbatch -showversion
+TESTFLAGS	= -Xbatch -Xmx32m -showversion
 
 ### maye ARCH_XXX instead?
 ifdef USE_GCC
--- a/hotspot/make/solaris/makefiles/vm.make	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/solaris/makefiles/vm.make	Wed Jan 19 19:00:30 2011 -0800
@@ -119,6 +119,10 @@
 LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
 endif # sparcWorks
 
+ifeq ("${Platform_arch}", "sparc")
+LIBS += -lkstat
+endif
+
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
 
--- a/hotspot/make/windows/makefiles/compile.make	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/make/windows/makefiles/compile.make	Wed Jan 19 19:00:30 2011 -0800
@@ -152,7 +152,7 @@
 !endif
 
 # Always add the _STATIC_CPPLIB flag
-STATIC_CPPLIB_OPTION = /D _STATIC_CPPLIB
+STATIC_CPPLIB_OPTION = /D _STATIC_CPPLIB /D _DISABLE_DEPRECATE_STATIC_CPPLIB
 MS_RUNTIME_OPTION = $(MS_RUNTIME_OPTION) $(STATIC_CPPLIB_OPTION)
 CPP_FLAGS=$(CPP_FLAGS) $(MS_RUNTIME_OPTION)
 
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "asm/assembler.hpp"
 #include "assembler_sparc.inline.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "interpreter/interpreter.hpp"
@@ -1327,37 +1328,38 @@
 }
 
 
-int MacroAssembler::size_of_sethi(address a, bool worst_case) {
+int MacroAssembler::insts_for_sethi(address a, bool worst_case) {
 #ifdef _LP64
-  if (worst_case) return 7;
-  intptr_t iaddr = (intptr_t)a;
-  int hi32 = (int)(iaddr >> 32);
-  int lo32 = (int)(iaddr);
-  int inst_count;
-  if (hi32 == 0 && lo32 >= 0)
-    inst_count = 1;
-  else if (hi32 == -1)
-    inst_count = 2;
+  if (worst_case)  return 7;
+  intptr_t iaddr = (intptr_t) a;
+  int msb32 = (int) (iaddr >> 32);
+  int lsb32 = (int) (iaddr);
+  int count;
+  if (msb32 == 0 && lsb32 >= 0)
+    count = 1;
+  else if (msb32 == -1)
+    count = 2;
   else {
-    inst_count = 2;
-    if ( hi32 & 0x3ff )
-      inst_count++;
-    if ( lo32 & 0xFFFFFC00 ) {
-      if( (lo32 >> 20) & 0xfff ) inst_count += 2;
-      if( (lo32 >> 10) & 0x3ff ) inst_count += 2;
+    count = 2;
+    if (msb32 & 0x3ff)
+      count++;
+    if (lsb32 & 0xFFFFFC00 ) {
+      if ((lsb32 >> 20) & 0xfff)  count += 2;
+      if ((lsb32 >> 10) & 0x3ff)  count += 2;
     }
   }
-  return BytesPerInstWord * inst_count;
+  return count;
 #else
-  return BytesPerInstWord;
+  return 1;
 #endif
 }
 
-int MacroAssembler::worst_case_size_of_set() {
-  return size_of_sethi(NULL, true) + 1;
+int MacroAssembler::worst_case_insts_for_set() {
+  return insts_for_sethi(NULL, true) + 1;
 }
 
 
+// Keep in sync with MacroAssembler::insts_for_internal_set
 void MacroAssembler::internal_set(const AddressLiteral& addrlit, Register d, bool ForceRelocatable) {
   intptr_t value = addrlit.value();
 
@@ -1379,6 +1381,23 @@
   }
 }
 
+// Keep in sync with MacroAssembler::internal_set
+int MacroAssembler::insts_for_internal_set(intptr_t value) {
+  // can optimize
+  if (-4096 <= value && value <= 4095) {
+    return 1;
+  }
+  if (inv_hi22(hi22(value)) == value) {
+    return insts_for_sethi((address) value);
+  }
+  int count = insts_for_sethi((address) value);
+  AddressLiteral al(value);
+  if (al.low10() != 0) {
+    count++;
+  }
+  return count;
+}
+
 void MacroAssembler::set(const AddressLiteral& al, Register d) {
   internal_set(al, d, false);
 }
@@ -1443,11 +1462,11 @@
   }
 }
 
-int MacroAssembler::size_of_set64(jlong value) {
+int MacroAssembler::insts_for_set64(jlong value) {
   v9_dep();
 
-  int hi = (int)(value >> 32);
-  int lo = (int)(value & ~0);
+  int hi = (int) (value >> 32);
+  int lo = (int) (value & ~0);
   int count = 0;
 
   // (Matcher::isSimpleConstant64 knows about the following optimizations.)
@@ -4083,11 +4102,15 @@
   store_klass(t2, top);
   verify_oop(top);
 
+  ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t1);
+  sub(top, t1, t1); // size of tlab's allocated portion
+  incr_allocated_bytes(t1, 0, t2);
+
   // refill the tlab with an eden allocation
   bind(do_refill);
   ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t1);
   sll_ptr(t1, LogHeapWordSize, t1);
-  // add object_size ??
+  // allocate new tlab, address returned in top
   eden_allocate(top, t1, 0, t2, t3, slow_case);
 
   st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_start_offset()));
@@ -4115,6 +4138,22 @@
   delayed()->nop();
 }
 
+void MacroAssembler::incr_allocated_bytes(Register var_size_in_bytes,
+                                          int con_size_in_bytes,
+                                          Register t1) {
+  // Bump total bytes allocated by this thread
+  assert(t1->is_global(), "must be global reg"); // so all 64 bits are saved on a context switch
+  assert_different_registers(var_size_in_bytes, t1);
+  // v8 support has gone the way of the dodo
+  ldx(G2_thread, in_bytes(JavaThread::allocated_bytes_offset()), t1);
+  if (var_size_in_bytes->is_valid()) {
+    add(t1, var_size_in_bytes, t1);
+  } else {
+    add(t1, con_size_in_bytes, t1);
+  }
+  stx(t1, G2_thread, in_bytes(JavaThread::allocated_bytes_offset()));
+}
+
 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
   switch (cond) {
     // Note some conditions are synonyms for others
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1884,23 +1884,24 @@
   void sethi(const AddressLiteral& addrlit, Register d);
   void patchable_sethi(const AddressLiteral& addrlit, Register d);
 
-  // compute the size of a sethi/set
-  static int  size_of_sethi( address a, bool worst_case = false );
-  static int  worst_case_size_of_set();
+  // compute the number of instructions for a sethi/set
+  static int  insts_for_sethi( address a, bool worst_case = false );
+  static int  worst_case_insts_for_set();
 
   // set may be either setsw or setuw (high 32 bits may be zero or sign)
 private:
   void internal_set(const AddressLiteral& al, Register d, bool ForceRelocatable);
+  static int insts_for_internal_set(intptr_t value);
 public:
   void set(const AddressLiteral& addrlit, Register d);
   void set(intptr_t value, Register d);
   void set(address addr, Register d, RelocationHolder const& rspec);
+  static int insts_for_set(intptr_t value) { return insts_for_internal_set(value); }
+
   void patchable_set(const AddressLiteral& addrlit, Register d);
   void patchable_set(intptr_t value, Register d);
   void set64(jlong value, Register d, Register tmp);
-
-  // Compute size of set64.
-  static int size_of_set64(jlong value);
+  static int insts_for_set64(jlong value);
 
   // sign-extend 32 to 64
   inline void signx( Register s, Register d ) { sra( s, G0, d); }
@@ -2388,6 +2389,7 @@
     Label&   slow_case                 // continuation point if fast allocation fails
   );
   void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
+  void incr_allocated_bytes(Register var_size_in_bytes, int con_size_in_bytes, Register t1);
 
   // interface method calling
   void lookup_interface_method(Register recv_klass,
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1705,8 +1705,7 @@
 }
 
 
-void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) {
-
+void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {
   Assembler::Condition acond;
   switch (condition) {
     case lir_cond_equal:        acond = Assembler::equal;        break;
@@ -1737,7 +1736,12 @@
     ShouldNotReachHere();
   }
   Label skip;
-  __ br(acond, false, Assembler::pt, skip);
+#ifdef _LP64
+    if  (type == T_INT) {
+      __ br(acond, false, Assembler::pt, skip);
+    } else
+#endif
+      __ brx(acond, false, Assembler::pt, skip); // checks icc on 32bit and xcc on 64bit
   if (opr1->is_constant() && opr1->type() == T_INT) {
     Register dest = result->as_register();
     if (Assembler::is_simm13(opr1->as_jint())) {
@@ -2688,6 +2692,11 @@
 #ifdef _LP64
     __ mov(cmp_value_lo, t1);
     __ mov(new_value_lo, t2);
+    // perform the compare and swap operation
+    __ casx(addr, t1, t2);
+    // generate condition code - if the swap succeeded, t2 ("new value" reg) was
+    // overwritten with the original value in "addr" and will be equal to t1.
+    __ cmp(t1, t2);
 #else
     // move high and low halves of long values into single registers
     __ sllx(cmp_value_hi, 32, t1);         // shift high half into temp reg
@@ -2696,13 +2705,15 @@
     __ sllx(new_value_hi, 32, t2);
     __ srl(new_value_lo, 0, new_value_lo);
     __ or3(t2, new_value_lo, t2);          // t2 holds 64-bit value to swap
-#endif
     // perform the compare and swap operation
     __ casx(addr, t1, t2);
     // generate condition code - if the swap succeeded, t2 ("new value" reg) was
     // overwritten with the original value in "addr" and will be equal to t1.
-    __ cmp(t1, t2);
-
+    // Produce icc flag for 32bit.
+    __ sub(t1, t2, t2);
+    __ srlx(t2, 32, t1);
+    __ orcc(t2, t1, G0);
+#endif
   } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) {
     Register addr = op->addr()->as_pointer_register();
     Register cmp_value = op->cmp_value()->as_register();
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -662,7 +662,7 @@
 
   // generate conditional move of boolean result
   LIR_Opr result = rlock_result(x);
-  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG);
 }
 
 
@@ -699,10 +699,10 @@
   else {
     ShouldNotReachHere();
   }
-
   // generate conditional move of boolean result
   LIR_Opr result = rlock_result(x);
-  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
+           result, as_BasicType(type));
   if (type == objectType) {  // Write-barrier needed for Object fields.
     // Precise card mark since could either be object or array
     post_barrier(addr, val.result());
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -166,7 +166,7 @@
   Register obj,                        // result: pointer to object after successful allocation
   Register var_size_in_bytes,          // object size in bytes if unknown at compile time; invalid otherwise
   int      con_size_in_bytes,          // object size in bytes if   known at compile time
-  Register t1,                         // temp register
+  Register t1,                         // temp register, must be global register for incr_allocated_bytes
   Register t2,                         // temp register
   Label&   slow_case                   // continuation point if fast allocation fails
 ) {
@@ -174,6 +174,7 @@
     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
   } else {
     eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
+    incr_allocated_bytes(var_size_in_bytes, con_size_in_bytes, t1);
   }
 }
 
@@ -214,7 +215,7 @@
 void C1_MacroAssembler::allocate_object(
   Register obj,                        // result: pointer to object after successful allocation
   Register t1,                         // temp register
-  Register t2,                         // temp register
+  Register t2,                         // temp register, must be a global register for try_allocate
   Register t3,                         // temp register
   int      hdr_size,                   // object header size in words
   int      obj_size,                   // object size in words
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -448,7 +448,9 @@
 
           // get the instance size
           __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
+
           __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
+
           __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
           __ verify_oop(O0_obj);
           __ mov(O0, I0);
@@ -459,6 +461,8 @@
           // get the instance size
           __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
           __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
+          __ incr_allocated_bytes(G1_obj_size, 0, G3_t1);
+
           __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
           __ verify_oop(O0_obj);
           __ mov(O0, I0);
@@ -573,6 +577,7 @@
           __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
 
           __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path);  // preserves G1_arr_size
+          __ incr_allocated_bytes(G1_arr_size, 0, G3_t1);
 
           __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
           __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -395,18 +395,23 @@
 //
 // Generate an "entry" field for a method handle.
 // This determines how the method handle will respond to calls.
-void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
+void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) {
   // Here is the register state during an interpreted call,
   // as set up by generate_method_handle_interpreter_entry():
   // - G5: garbage temp (was MethodHandle.invoke methodOop, unused)
   // - G3: receiver method handle
   // - O5_savedSP: sender SP (must preserve)
 
-  Register O0_argslot = O0;
-  Register O1_scratch = O1;
-  Register O2_scratch = O2;
-  Register O3_scratch = O3;
-  Register G5_index   = G5;
+  const Register O0_argslot = O0;
+  const Register O1_scratch = O1;
+  const Register O2_scratch = O2;
+  const Register O3_scratch = O3;
+  const Register G5_index   = G5;
+
+  // Argument registers for _raise_exception.
+  const Register O0_code     = O0;
+  const Register O1_actual   = O1;
+  const Register O2_required = O2;
 
   guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
 
@@ -439,48 +444,36 @@
   case _raise_exception:
     {
       // Not a real MH entry, but rather shared code for raising an
-      // exception.  Extra local arguments are passed in scratch
-      // registers, as required type in O3, failing object (or NULL)
-      // in O2, failing bytecode type in O1.
+      // exception.  Since we use a C2I adapter to set up the
+      // interpreter state, arguments are expected in compiler
+      // argument registers.
+      methodHandle mh(raise_exception_method());
+      address c2i_entry = methodOopDesc::make_adapters(mh, CATCH);
 
       __ mov(O5_savedSP, SP);  // Cut the stack back to where the caller started.
 
-      // Push arguments as if coming from the interpreter.
-      Register O0_scratch = O0_argslot;
-      int stackElementSize = Interpreter::stackElementSize;
-
-      // Make space on the stack for the arguments and set Gargs
-      // correctly.
-      __ sub(SP, 4*stackElementSize, SP);  // Keep stack aligned.
-      __ add(SP, (frame::varargs_offset)*wordSize - 1*Interpreter::stackElementSize + STACK_BIAS + BytesPerWord, Gargs);
-
-      // void raiseException(int code, Object actual, Object required)
-      __ st(    O1_scratch, Address(Gargs, 2*stackElementSize));  // code
-      __ st_ptr(O2_scratch, Address(Gargs, 1*stackElementSize));  // actual
-      __ st_ptr(O3_scratch, Address(Gargs, 0*stackElementSize));  // required
-
-      Label no_method;
+      Label L_no_method;
       // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
       __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
       __ ld_ptr(Address(G5_method, 0), G5_method);
       __ tst(G5_method);
-      __ brx(Assembler::zero, false, Assembler::pn, no_method);
+      __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
       __ delayed()->nop();
 
-      int jobject_oop_offset = 0;
+      const int jobject_oop_offset = 0;
       __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
       __ tst(G5_method);
-      __ brx(Assembler::zero, false, Assembler::pn, no_method);
+      __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
       __ delayed()->nop();
 
       __ verify_oop(G5_method);
-      __ jump_indirect_to(G5_method_fie, O1_scratch);
+      __ jump_to(AddressLiteral(c2i_entry), O3_scratch);
       __ delayed()->nop();
 
       // If we get here, the Java runtime did not do its job of creating the exception.
       // Do something that is at least causes a valid throw from the interpreter.
-      __ bind(no_method);
-      __ unimplemented("_raise_exception no method");
+      __ bind(L_no_method);
+      __ unimplemented("call throw_WrongMethodType_entry");
     }
     break;
 
@@ -570,10 +563,10 @@
       // Throw an exception.
       // For historical reasons, it will be IncompatibleClassChangeError.
       __ unimplemented("not tested yet");
-      __ ld_ptr(Address(O1_intf, java_mirror_offset), O3_scratch);  // required interface
-      __ mov(O0_klass, O2_scratch);  // bad receiver
-      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
-      __ delayed()->mov(Bytecodes::_invokeinterface, O1_scratch);  // who is complaining?
+      __ ld_ptr(Address(O1_intf, java_mirror_offset), O2_required);  // required interface
+      __ mov(   O0_klass,                             O1_actual);    // bad receiver
+      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
+      __ delayed()->mov(Bytecodes::_invokeinterface,  O0_code);      // who is complaining?
     }
     break;
 
@@ -663,11 +656,10 @@
       __ check_klass_subtype(O1_scratch, G5_klass, O0_argslot, O2_scratch, done);
 
       // If we get here, the type check failed!
-      __ ldsw(G3_amh_vmargslot, O0_argslot);  // reload argslot field
-      __ load_heap_oop(G3_amh_argument, O3_scratch);  // required class
-      __ ld_ptr(vmarg, O2_scratch);  // bad object
-      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
-      __ delayed()->mov(Bytecodes::_checkcast, O1_scratch);  // who is complaining?
+      __ load_heap_oop(G3_amh_argument,        O2_required);  // required class
+      __ ld_ptr(       vmarg,                  O1_actual);    // bad object
+      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
+      __ delayed()->mov(Bytecodes::_checkcast, O0_code);      // who is complaining?
 
       __ bind(done);
       // Get the new MH:
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jan 19 19:00:30 2011 -0800
@@ -1086,9 +1086,9 @@
 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
   if (UseRDPCForConstantTableBase) {
     // This is really the worst case but generally it's only 1 instruction.
-    return 4 /*rdpc*/ + 4 /*sub*/ + MacroAssembler::worst_case_size_of_set();
+    return (1 /*rdpc*/ + 1 /*sub*/ + MacroAssembler::worst_case_insts_for_set()) * BytesPerInstWord;
   } else {
-    return MacroAssembler::worst_case_size_of_set();
+    return MacroAssembler::worst_case_insts_for_set() * BytesPerInstWord;
   }
 }
 
@@ -1240,7 +1240,7 @@
 
 int MachEpilogNode::safepoint_offset() const {
   assert( do_polling(), "no return for this epilog node");
-  return MacroAssembler::size_of_sethi(os::get_polling_page());
+  return MacroAssembler::insts_for_sethi(os::get_polling_page()) * BytesPerInstWord;
 }
 
 //=============================================================================
@@ -3553,9 +3553,10 @@
   interface(CONST_INTER);
 %}
 
-// Pointer Immediate: 32 or 64-bit
+#ifdef _LP64
+// Pointer Immediate: 64-bit
 operand immP_set() %{
-  predicate(!VM_Version::is_niagara1_plus());
+  predicate(!VM_Version::is_niagara_plus());
   match(ConP);
 
   op_cost(5);
@@ -3564,10 +3565,10 @@
   interface(CONST_INTER);
 %}
 
-// Pointer Immediate: 32 or 64-bit
+// Pointer Immediate: 64-bit
 // From Niagara2 processors on a load should be better than materializing.
 operand immP_load() %{
-  predicate(VM_Version::is_niagara1_plus());
+  predicate(VM_Version::is_niagara_plus() && (n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set(n->get_ptr()) > 3)));
   match(ConP);
 
   op_cost(5);
@@ -3576,6 +3577,18 @@
   interface(CONST_INTER);
 %}
 
+// Pointer Immediate: 64-bit
+operand immP_no_oop_cheap() %{
+  predicate(VM_Version::is_niagara_plus() && !n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set(n->get_ptr()) <= 3));
+  match(ConP);
+
+  op_cost(5);
+  // formats are generated automatically for constants and base registers
+  format %{ %}
+  interface(CONST_INTER);
+%}
+#endif
+
 operand immP13() %{
   predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095));
   match(ConP);
@@ -3673,7 +3686,7 @@
 
 // Long Immediate: cheap (materialize in <= 3 instructions)
 operand immL_cheap() %{
-  predicate(!VM_Version::is_niagara1_plus() || MacroAssembler::size_of_set64(n->get_long()) <= 3);
+  predicate(!VM_Version::is_niagara_plus() || MacroAssembler::insts_for_set64(n->get_long()) <= 3);
   match(ConL);
   op_cost(0);
 
@@ -3683,7 +3696,7 @@
 
 // Long Immediate: expensive (materialize in > 3 instructions)
 operand immL_expensive() %{
-  predicate(VM_Version::is_niagara1_plus() && MacroAssembler::size_of_set64(n->get_long()) > 3);
+  predicate(VM_Version::is_niagara_plus() && MacroAssembler::insts_for_set64(n->get_long()) > 3);
   match(ConL);
   op_cost(0);
 
@@ -6094,8 +6107,18 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "LD     [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %}
   ins_encode %{
-      RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
-     __ ld_ptr($constanttablebase, con_offset, $dst$$Register);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
+    __ ld_ptr($constanttablebase, con_offset, $dst$$Register);
+  %}
+  ins_pipe(loadConP);
+%}
+
+instruct loadConP_no_oop_cheap(iRegP dst, immP_no_oop_cheap con) %{
+  match(Set dst con);
+  ins_cost(DEFAULT_COST * 3/2);
+  format %{ "SET    $con,$dst\t! non-oop ptr" %}
+  ins_encode %{
+    __ set($con$$constant, $dst$$Register);
   %}
   ins_pipe(loadConP);
 %}
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3393,21 +3393,21 @@
     __ delayed()->st_ptr(RnewTopValue, G2_thread, in_bytes(JavaThread::tlab_top_offset()));
 
     if (allow_shared_alloc) {
-    // Check if tlab should be discarded (refill_waste_limit >= free)
-    __ ld_ptr(G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), RtlabWasteLimitValue);
-    __ sub(RendValue, RoldTopValue, RfreeValue);
+      // Check if tlab should be discarded (refill_waste_limit >= free)
+      __ ld_ptr(G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), RtlabWasteLimitValue);
+      __ sub(RendValue, RoldTopValue, RfreeValue);
 #ifdef _LP64
-    __ srlx(RfreeValue, LogHeapWordSize, RfreeValue);
+      __ srlx(RfreeValue, LogHeapWordSize, RfreeValue);
 #else
-    __ srl(RfreeValue, LogHeapWordSize, RfreeValue);
+      __ srl(RfreeValue, LogHeapWordSize, RfreeValue);
 #endif
-    __ cmp(RtlabWasteLimitValue, RfreeValue);
-    __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, slow_case); // tlab waste is small
-    __ delayed()->nop();
-
-    // increment waste limit to prevent getting stuck on this slow path
-    __ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue);
-    __ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
+      __ cmp(RtlabWasteLimitValue, RfreeValue);
+      __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, slow_case); // tlab waste is small
+      __ delayed()->nop();
+
+      // increment waste limit to prevent getting stuck on this slow path
+      __ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue);
+      __ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
     } else {
       // No allocation in the shared eden.
       __ br(Assembler::always, false, Assembler::pt, slow_case);
@@ -3445,6 +3445,9 @@
     __ cmp(RoldTopValue, RnewTopValue);
     __ brx(Assembler::notEqual, false, Assembler::pn, retry);
     __ delayed()->nop();
+
+    // bump total bytes allocated by this thread
+    __ incr_allocated_bytes(Roffset, 0, G1_scratch);
   }
 
   if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -38,12 +38,6 @@
 int VM_Version::_features = VM_Version::unknown_m;
 const char* VM_Version::_features_str = "";
 
-bool VM_Version::is_niagara1_plus() {
-  // This is a placeholder until the real test is determined.
-  return is_niagara1() &&
-    (os::processor_count() > maximum_niagara1_processor_count());
-}
-
 void VM_Version::initialize() {
   _features = determine_features();
   PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes();
@@ -69,11 +63,21 @@
 
   _supports_cx8               = has_v9();
 
-  if (is_niagara1()) {
+  if (is_niagara()) {
     // Indirect branch is the same cost as direct
     if (FLAG_IS_DEFAULT(UseInlineCaches)) {
       FLAG_SET_DEFAULT(UseInlineCaches, false);
     }
+    // Align loops on a single instruction boundary.
+    if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
+      FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
+    }
+    // When using CMS, we cannot use memset() in BOT updates because
+    // the sun4v/CMT version in libc_psr uses BIS which exposes
+    // "phantom zeros" to concurrent readers. See 6948537.
+    if (FLAG_IS_DEFAULT(UseMemSetInBOT) && UseConcMarkSweepGC) {
+      FLAG_SET_DEFAULT(UseMemSetInBOT, false);
+    }
 #ifdef _LP64
     // 32-bit oops don't make sense for the 64-bit VM on sparc
     // since the 32-bit VM has the same registers and smaller objects.
@@ -89,7 +93,7 @@
     if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
       FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
     }
-    if (is_niagara1_plus()) {
+    if (is_niagara_plus()) {
       if (has_blk_init() && AllocatePrefetchStyle > 0 &&
           FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
         // Use BIS instruction for allocation prefetch.
@@ -105,15 +109,6 @@
       }
     }
 #endif
-    if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
-      FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
-    }
-    // When using CMS, we cannot use memset() in BOT updates because
-    // the sun4v/CMT version in libc_psr uses BIS which exposes
-    // "phantom zeros" to concurrent readers. See 6948537.
-    if (FLAG_IS_DEFAULT(UseMemSetInBOT) && UseConcMarkSweepGC) {
-      FLAG_SET_DEFAULT(UseMemSetInBOT, false);
-    }
   }
 
   // Use hardware population count instruction if available.
@@ -129,17 +124,18 @@
 #endif
 
   char buf[512];
-  jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+  jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                (has_v8() ? ", has_v8" : ""),
                (has_v9() ? ", has_v9" : ""),
                (has_hardware_popc() ? ", popc" : ""),
                (has_vis1() ? ", has_vis1" : ""),
                (has_vis2() ? ", has_vis2" : ""),
+               (has_vis3() ? ", has_vis3" : ""),
                (has_blk_init() ? ", has_blk_init" : ""),
                (is_ultra3() ? ", is_ultra3" : ""),
                (is_sun4v() ? ", is_sun4v" : ""),
-               (is_niagara1() ? ", is_niagara1" : ""),
-               (is_niagara1_plus() ? ", is_niagara1_plus" : ""),
+               (is_niagara() ? ", is_niagara" : ""),
+               (is_niagara_plus() ? ", is_niagara_plus" : ""),
                (is_sparc64() ? ", is_sparc64" : ""),
                (!has_hardware_mul32() ? ", no-mul32" : ""),
                (!has_hardware_div32() ? ", no-div32" : ""),
@@ -190,17 +186,18 @@
     warning("Cannot recognize SPARC version. Default to V9");
   }
 
-  if (UseNiagaraInstrs) {
-    if (is_niagara1(features)) {
+  assert(is_T_family(features) == is_niagara(features), "Niagara should be T series");
+  if (UseNiagaraInstrs) { // Force code generation for Niagara
+    if (is_T_family(features)) {
       // Happy to accomodate...
     } else {
       NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Version is Forced-Niagara");)
-      features = niagara1_m;
+      features |= T_family_m;
     }
   } else {
-    if (is_niagara1(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
+    if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
       NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Version is Forced-Not-Niagara");)
-      features &= ~niagara1_unique_m;
+      features &= ~(T_family_m | T1_model_m);
     } else {
       // Happy to accomodate...
     }
@@ -222,7 +219,7 @@
 
 unsigned int VM_Version::calc_parallel_worker_threads() {
   unsigned int result;
-  if (is_niagara1_plus()) {
+  if (is_niagara_plus()) {
     result = nof_parallel_worker_threads(5, 16, 8);
   } else {
     result = nof_parallel_worker_threads(5, 8, 8);
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -41,7 +41,12 @@
     vis2_instructions  = 7,
     sun4v_instructions = 8,
     blk_init_instructions = 9,
-    fmaf_instructions  = 10
+    fmaf_instructions  = 10,
+    fmau_instructions  = 11,
+    vis3_instructions  = 12,
+    sparc64_family     = 13,
+    T_family           = 14,
+    T1_model           = 15
   };
 
   enum Feature_Flag_Set {
@@ -59,6 +64,11 @@
     sun4v_m             = 1 << sun4v_instructions,
     blk_init_instructions_m = 1 << blk_init_instructions,
     fmaf_instructions_m = 1 << fmaf_instructions,
+    fmau_instructions_m = 1 << fmau_instructions,
+    vis3_instructions_m = 1 << vis3_instructions,
+    sparc64_family_m    = 1 << sparc64_family,
+    T_family_m          = 1 << T_family,
+    T1_model_m          = 1 << T1_model,
 
     generic_v8_m        = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
     generic_v9_m        = generic_v8_m | v9_instructions_m,
@@ -76,8 +86,13 @@
   static int  determine_features();
   static int  platform_features(int features);
 
-  static bool is_niagara1(int features) { return (features & sun4v_m) != 0; }
-  static bool  is_sparc64(int features) { return (features & fmaf_instructions_m) != 0; }
+  // Returns true if the platform is in the niagara line (T series)
+  static bool is_T_family(int features) { return (features & T_family_m) != 0; }
+  static bool is_niagara() { return is_T_family(_features); }
+  DEBUG_ONLY( static bool is_niagara(int features)  { return (features & sun4v_m) != 0; } )
+
+  // Returns true if it is niagara1 (T1).
+  static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
 
   static int maximum_niagara1_processor_count() { return 32; }
 
@@ -94,6 +109,7 @@
   static bool has_hardware_popc()       { return (_features & hardware_popc_m) != 0; }
   static bool has_vis1()                { return (_features & vis1_instructions_m) != 0; }
   static bool has_vis2()                { return (_features & vis2_instructions_m) != 0; }
+  static bool has_vis3()                { return (_features & vis3_instructions_m) != 0; }
   static bool has_blk_init()            { return (_features & blk_init_instructions_m) != 0; }
 
   static bool supports_compare_and_exchange()
@@ -101,14 +117,14 @@
 
   static bool is_ultra3()               { return (_features & ultra3_m) == ultra3_m; }
   static bool is_sun4v()                { return (_features & sun4v_m) != 0; }
-  static bool is_niagara1()             { return is_niagara1(_features); }
-  // Returns true if the platform is in the niagara line and
-  // newer than the niagara1.
-  static bool is_niagara1_plus();
-  static bool is_sparc64()              { return is_sparc64(_features); }
+  // Returns true if the platform is in the niagara line (T series)
+  // and newer than the niagara1.
+  static bool is_niagara_plus()         { return is_T_family(_features) && !is_T1_model(_features); }
+  // Fujitsu SPARC64
+  static bool is_sparc64()              { return (_features & sparc64_family_m) != 0; }
 
-  static bool has_fast_fxtof()          { return has_v9() && !is_ultra3(); }
-  static bool has_fast_idiv()           { return is_niagara1_plus() || is_sparc64(); }
+  static bool has_fast_fxtof()          { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); }
+  static bool has_fast_idiv()           { return is_niagara_plus() || is_sparc64(); }
 
   static const char* cpu_features()     { return _features_str; }
 
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -820,7 +820,20 @@
 }
 
 
-// Now the Assembler instruction (identical for 32/64 bits)
+// Now the Assembler instructions (identical for 32/64 bits)
+
+void Assembler::adcl(Address dst, int32_t imm32) {
+  InstructionMark im(this);
+  prefix(dst);
+  emit_arith_operand(0x81, rdx, dst, imm32);
+}
+
+void Assembler::adcl(Address dst, Register src) {
+  InstructionMark im(this);
+  prefix(dst, src);
+  emit_byte(0x11);
+  emit_operand(src, dst);
+}
 
 void Assembler::adcl(Register dst, int32_t imm32) {
   prefix(dst);
@@ -2195,9 +2208,7 @@
 void Assembler::orl(Address dst, int32_t imm32) {
   InstructionMark im(this);
   prefix(dst);
-  emit_byte(0x81);
-  emit_operand(rcx, dst, 4);
-  emit_long(imm32);
+  emit_arith_operand(0x81, rcx, dst, imm32);
 }
 
 void Assembler::orl(Register dst, int32_t imm32) {
@@ -2205,7 +2216,6 @@
   emit_arith(0x81, 0xC8, dst, imm32);
 }
 
-
 void Assembler::orl(Register dst, Address src) {
   InstructionMark im(this);
   prefix(src, dst);
@@ -2213,7 +2223,6 @@
   emit_operand(dst, src);
 }
 
-
 void Assembler::orl(Register dst, Register src) {
   (void) prefix_and_encode(dst->encoding(), src->encoding());
   emit_arith(0x0B, 0xC0, dst, src);
@@ -2692,20 +2701,7 @@
 void Assembler::subl(Address dst, int32_t imm32) {
   InstructionMark im(this);
   prefix(dst);
-  if (is8bit(imm32)) {
-    emit_byte(0x83);
-    emit_operand(rbp, dst, 1);
-    emit_byte(imm32 & 0xFF);
-  } else {
-    emit_byte(0x81);
-    emit_operand(rbp, dst, 4);
-    emit_long(imm32);
-  }
-}
-
-void Assembler::subl(Register dst, int32_t imm32) {
-  prefix(dst);
-  emit_arith(0x81, 0xE8, dst, imm32);
+  emit_arith_operand(0x81, rbp, dst, imm32);
 }
 
 void Assembler::subl(Address dst, Register src) {
@@ -2715,6 +2711,11 @@
   emit_operand(src, dst);
 }
 
+void Assembler::subl(Register dst, int32_t imm32) {
+  prefix(dst);
+  emit_arith(0x81, 0xE8, dst, imm32);
+}
+
 void Assembler::subl(Register dst, Address src) {
   InstructionMark im(this);
   prefix(src, dst);
@@ -4333,6 +4334,7 @@
   emit_byte(0xD3);
   emit_byte(0xF8 | encode);
 }
+
 void Assembler::sbbq(Address dst, int32_t imm32) {
   InstructionMark im(this);
   prefixq(dst);
@@ -4392,20 +4394,7 @@
 void Assembler::subq(Address dst, int32_t imm32) {
   InstructionMark im(this);
   prefixq(dst);
-  if (is8bit(imm32)) {
-    emit_byte(0x83);
-    emit_operand(rbp, dst, 1);
-    emit_byte(imm32 & 0xFF);
-  } else {
-    emit_byte(0x81);
-    emit_operand(rbp, dst, 4);
-    emit_long(imm32);
-  }
-}
-
-void Assembler::subq(Register dst, int32_t imm32) {
-  (void) prefixq_and_encode(dst->encoding());
-  emit_arith(0x81, 0xE8, dst, imm32);
+  emit_arith_operand(0x81, rbp, dst, imm32);
 }
 
 void Assembler::subq(Address dst, Register src) {
@@ -4415,6 +4404,11 @@
   emit_operand(src, dst);
 }
 
+void Assembler::subq(Register dst, int32_t imm32) {
+  (void) prefixq_and_encode(dst->encoding());
+  emit_arith(0x81, 0xE8, dst, imm32);
+}
+
 void Assembler::subq(Register dst, Address src) {
   InstructionMark im(this);
   prefixq(src, dst);
@@ -7136,9 +7130,9 @@
 }
 
 // Preserves rbx, and rdx.
-void MacroAssembler::tlab_refill(Label& retry,
-                                 Label& try_eden,
-                                 Label& slow_case) {
+Register MacroAssembler::tlab_refill(Label& retry,
+                                     Label& try_eden,
+                                     Label& slow_case) {
   Register top = rax;
   Register t1  = rcx;
   Register t2  = rsi;
@@ -7185,7 +7179,7 @@
 
   // if tlab is currently allocated (top or end != null) then
   // fill [top, end + alignment_reserve) with array object
-  testptr (top, top);
+  testptr(top, top);
   jcc(Assembler::zero, do_refill);
 
   // set up the mark word
@@ -7197,16 +7191,20 @@
   movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
   // set klass to intArrayKlass
   // dubious reloc why not an oop reloc?
-  movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
+  movptr(t1, ExternalAddress((address)Universe::intArrayKlassObj_addr()));
   // store klass last.  concurrent gcs assumes klass length is valid if
   // klass field is not null.
   store_klass(top, t1);
 
+  movptr(t1, top);
+  subptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
+  incr_allocated_bytes(thread_reg, t1, 0);
+
   // refill the tlab with an eden allocation
   bind(do_refill);
   movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
   shlptr(t1, LogHeapWordSize);
-  // add object_size ??
+  // allocate new tlab, address returned in top
   eden_allocate(top, t1, 0, t2, slow_case);
 
   // Check that t1 was preserved in eden_allocate.
@@ -7234,6 +7232,34 @@
   movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top);
   verify_tlab();
   jmp(retry);
+
+  return thread_reg; // for use by caller
+}
+
+void MacroAssembler::incr_allocated_bytes(Register thread,
+                                          Register var_size_in_bytes,
+                                          int con_size_in_bytes,
+                                          Register t1) {
+#ifdef _LP64
+  if (var_size_in_bytes->is_valid()) {
+    addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
+  } else {
+    addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
+  }
+#else
+  if (!thread->is_valid()) {
+    assert(t1->is_valid(), "need temp reg");
+    thread = t1;
+    get_thread(thread);
+  }
+
+  if (var_size_in_bytes->is_valid()) {
+    addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
+  } else {
+    addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
+  }
+  adcl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())+4), 0);
+#endif
 }
 
 static const double     pi_4 =  0.7853981633974483;
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -674,12 +674,14 @@
   // Utilities
 
 #ifdef _LP64
- static bool is_simm(int64_t x, int nbits) { return -( CONST64(1) << (nbits-1) )  <= x   &&   x  <  ( CONST64(1) << (nbits-1) ); }
+ static bool is_simm(int64_t x, int nbits) { return -(CONST64(1) << (nbits-1)) <= x &&
+                                                    x < (CONST64(1) << (nbits-1)); }
  static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; }
 #else
- static bool is_simm(int32_t x, int nbits) { return -( 1 << (nbits-1) )  <= x   &&   x  <  ( 1 << (nbits-1) ); }
+ static bool is_simm(int32_t x, int nbits) { return -(1 << (nbits-1)) <= x &&
+                                                    x < (1 << (nbits-1)); }
  static bool is_simm32(int32_t x) { return true; }
-#endif // LP64
+#endif // _LP64
 
   // Generic instructions
   // Does 32bit or 64bit as needed for the platform. In some sense these
@@ -705,7 +707,6 @@
   void push(void* v);
   void pop(void* v);
 
-
   // These do register sized moves/scans
   void rep_mov();
   void rep_set();
@@ -716,6 +717,8 @@
 
   // Vanilla instructions in lexical order
 
+  void adcl(Address dst, int32_t imm32);
+  void adcl(Address dst, Register src);
   void adcl(Register dst, int32_t imm32);
   void adcl(Register dst, Address src);
   void adcl(Register dst, Register src);
@@ -724,7 +727,6 @@
   void adcq(Register dst, Address src);
   void adcq(Register dst, Register src);
 
-
   void addl(Address dst, int32_t imm32);
   void addl(Address dst, Register src);
   void addl(Register dst, int32_t imm32);
@@ -737,7 +739,6 @@
   void addq(Register dst, Address src);
   void addq(Register dst, Register src);
 
-
   void addr_nop_4();
   void addr_nop_5();
   void addr_nop_7();
@@ -759,7 +760,6 @@
   void andq(Register dst, Address src);
   void andq(Register dst, Register src);
 
-
   // Bitwise Logical AND of Packed Double-Precision Floating-Point Values
   void andpd(XMMRegister dst, Address src);
   void andpd(XMMRegister dst, XMMRegister src);
@@ -1151,7 +1151,7 @@
 #ifdef _LP64
   void movq(Register dst, Register src);
   void movq(Register dst, Address src);
-  void movq(Address dst, Register src);
+  void movq(Address  dst, Register src);
 #endif
 
   void movq(Address     dst, MMXRegister src );
@@ -1177,7 +1177,7 @@
   void movsbq(Register dst, Register src);
 
   // Move signed 32bit immediate to 64bit extending sign
-  void movslq(Address dst, int32_t imm64);
+  void movslq(Address  dst, int32_t imm64);
   void movslq(Register dst, int32_t imm64);
 
   void movslq(Register dst, Address src);
@@ -1857,7 +1857,10 @@
     Register t2,                       // temp register
     Label&   slow_case                 // continuation point if fast allocation fails
   );
-  void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
+  Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
+  void incr_allocated_bytes(Register thread,
+                            Register var_size_in_bytes, int con_size_in_bytes,
+                            Register t1 = noreg);
 
   // interface method calling
   void lookup_interface_method(Register recv_klass,
@@ -2180,9 +2183,9 @@
   void divss(XMMRegister dst, Address src)        { Assembler::divss(dst, src); }
   void divss(XMMRegister dst, AddressLiteral src) { Assembler::divss(dst, as_Address(src)); }
 
-  void movsd(XMMRegister dst, XMMRegister src)    { Assembler::movsd(dst, src); }
-  void movsd(Address dst, XMMRegister src)        { Assembler::movsd(dst, src); }
-  void movsd(XMMRegister dst, Address src)        { Assembler::movsd(dst, src); }
+  void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); }
+  void movsd(Address dst, XMMRegister src)     { Assembler::movsd(dst, src); }
+  void movsd(XMMRegister dst, Address src)     { Assembler::movsd(dst, src); }
   void movsd(XMMRegister dst, AddressLiteral src) { Assembler::movsd(dst, as_Address(src)); }
 
   void mulsd(XMMRegister dst, XMMRegister src)    { Assembler::mulsd(dst, src); }
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -2036,7 +2036,7 @@
   }
 }
 
-void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) {
+void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {
   Assembler::Condition acond, ncond;
   switch (condition) {
     case lir_cond_equal:        acond = Assembler::equal;        ncond = Assembler::notEqual;     break;
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -741,7 +741,7 @@
 
   // generate conditional move of boolean result
   LIR_Opr result = rlock_result(x);
-  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG);
 }
 
 
@@ -810,7 +810,8 @@
 
   // generate conditional move of boolean result
   LIR_Opr result = rlock_result(x);
-  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
+  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
+           result, as_BasicType(type));
   if (type == objectType) {   // Write-barrier needed for Object fields.
     // Seems to be precise
     post_barrier(addr, val.result());
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -141,6 +141,7 @@
     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
   } else {
     eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
+    incr_allocated_bytes(noreg, var_size_in_bytes, con_size_in_bytes, t1);
   }
 }
 
@@ -234,7 +235,7 @@
 
 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
   assert(obj == rax, "obj must be in rax, for cmpxchg");
-  assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really?
+  assert_different_registers(obj, t1, t2); // XXX really?
   assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
 
   try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -977,7 +977,6 @@
         // verify that that there is really a valid exception in rax,
         __ verify_not_null_oop(exception_oop);
 
-
         oop_maps = new OopMapSet();
         OopMap* oop_map = generate_oop_map(sasm, 1);
         generate_handle_exception(sasm, oop_maps, oop_map);
@@ -1037,13 +1036,16 @@
           // if we got here then the TLAB allocation failed, so try
           // refilling the TLAB or allocating directly from eden.
           Label retry_tlab, try_eden;
-          __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass)
+          const Register thread =
+            __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass), returns rdi
 
           __ bind(retry_tlab);
 
           // get the instance size (size is postive so movl is fine for 64bit)
           __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
+
           __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
+
           __ initialize_object(obj, klass, obj_size, 0, t1, t2);
           __ verify_oop(obj);
           __ pop(rbx);
@@ -1053,7 +1055,10 @@
           __ bind(try_eden);
           // get the instance size (size is postive so movl is fine for 64bit)
           __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
+
           __ eden_allocate(obj, obj_size, 0, t1, slow_path);
+          __ incr_allocated_bytes(thread, obj_size, 0);
+
           __ initialize_object(obj, klass, obj_size, 0, t1, t2);
           __ verify_oop(obj);
           __ pop(rbx);
@@ -1143,12 +1148,13 @@
           // if we got here then the TLAB allocation failed, so try
           // refilling the TLAB or allocating directly from eden.
           Label retry_tlab, try_eden;
-          __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx, & rdx
+          const Register thread =
+            __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx & rdx, returns rdi
 
           __ bind(retry_tlab);
 
           // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
-          // since size is postive movl does right thing on 64bit
+          // since size is positive movl does right thing on 64bit
           __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
           // since size is postive movl does right thing on 64bit
           __ movl(arr_size, length);
@@ -1175,7 +1181,7 @@
 
           __ bind(try_eden);
           // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
-          // since size is postive movl does right thing on 64bit
+          // since size is positive movl does right thing on 64bit
           __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes()));
           // since size is postive movl does right thing on 64bit
           __ movl(arr_size, length);
@@ -1188,6 +1194,7 @@
           __ andptr(arr_size, ~MinObjAlignmentInBytesMask);
 
           __ eden_allocate(obj, arr_size, 0, t1, slow_path);  // preserves arr_size
+          __ incr_allocated_bytes(thread, arr_size, 0);
 
           __ initialize_header(obj, klass, length, t1, t2);
           __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte)));
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -385,9 +385,12 @@
   // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
 }
 
+//------------------------------------------------------------------------------
+// MethodHandles::generate_method_handle_stub
+//
 // Generate an "entry" field for a method handle.
 // This determines how the method handle will respond to calls.
-void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
+void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) {
   // Here is the register state during an interpreted call,
   // as set up by generate_method_handle_interpreter_entry():
   // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused)
@@ -396,14 +399,21 @@
   // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
   // - rdx: garbage temp, can blow away
 
-  Register rcx_recv    = rcx;
-  Register rax_argslot = rax;
-  Register rbx_temp    = rbx;
-  Register rdx_temp    = rdx;
+  const Register rcx_recv    = rcx;
+  const Register rax_argslot = rax;
+  const Register rbx_temp    = rbx;
+  const Register rdx_temp    = rdx;
 
   // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
   // and gen_c2i_adapter (from compiled calls):
-  Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
+  const Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
+
+  // Argument registers for _raise_exception.
+  // 32-bit: Pass first two oop/int args in registers ECX and EDX.
+  const Register rarg0_code     = LP64_ONLY(j_rarg0) NOT_LP64(rcx);
+  const Register rarg1_actual   = LP64_ONLY(j_rarg1) NOT_LP64(rdx);
+  const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
+  assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp);
 
   guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
 
@@ -437,47 +447,41 @@
   switch ((int) ek) {
   case _raise_exception:
     {
-      // Not a real MH entry, but rather shared code for raising an exception.
-      // Extra local arguments are pushed on stack, as required type at TOS+8,
-      // failing object (or NULL) at TOS+4, failing bytecode type at TOS.
-      // Beyond those local arguments are the PC, of course.
-      Register rdx_code = rdx_temp;
-      Register rcx_fail = rcx_recv;
-      Register rax_want = rax_argslot;
-      Register rdi_pc   = rdi;
-      __ pop(rdx_code);  // TOS+0
-      __ pop(rcx_fail);  // TOS+4
-      __ pop(rax_want);  // TOS+8
-      __ pop(rdi_pc);    // caller PC
+      // Not a real MH entry, but rather shared code for raising an
+      // exception.  Since we use a C2I adapter to set up the
+      // interpreter state, arguments are expected in compiler
+      // argument registers.
+      methodHandle mh(raise_exception_method());
+      address c2i_entry = methodOopDesc::make_adapters(mh, CHECK);
 
-      __ mov(rsp, rsi);   // cut the stack back to where the caller started
-
-      // Repush the arguments as if coming from the interpreter.
-      __ push(rdx_code);
-      __ push(rcx_fail);
-      __ push(rax_want);
+      const Register rdi_pc = rax;
+      __ pop(rdi_pc);  // caller PC
+      __ mov(rsp, saved_last_sp);  // cut the stack back to where the caller started
 
       Register rbx_method = rbx_temp;
-      Label no_method;
+      Label L_no_method;
       // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
       __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
       __ testptr(rbx_method, rbx_method);
-      __ jccb(Assembler::zero, no_method);
-      int jobject_oop_offset = 0;
+      __ jccb(Assembler::zero, L_no_method);
+
+      const int jobject_oop_offset = 0;
       __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset));  // dereference the jobject
       __ testptr(rbx_method, rbx_method);
-      __ jccb(Assembler::zero, no_method);
+      __ jccb(Assembler::zero, L_no_method);
       __ verify_oop(rbx_method);
-      __ push(rdi_pc);          // and restore caller PC
-      __ jmp(rbx_method_fie);
+
+      // 32-bit: push remaining arguments as if coming from the compiler.
+      NOT_LP64(__ push(rarg2_required));
+
+      __ push(rdi_pc);  // restore caller PC
+      __ jump(ExternalAddress(c2i_entry));  // do C2I transition
 
       // If we get here, the Java runtime did not do its job of creating the exception.
       // Do something that is at least causes a valid throw from the interpreter.
-      __ bind(no_method);
-      __ pop(rax_want);
-      __ pop(rcx_fail);
-      __ push(rax_want);
-      __ push(rcx_fail);
+      __ bind(L_no_method);
+      __ push(rarg2_required);
+      __ push(rarg1_actual);
       __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
     }
     break;
@@ -572,9 +576,11 @@
       __ bind(no_such_interface);
       // Throw an exception.
       // For historical reasons, it will be IncompatibleClassChangeError.
-      __ pushptr(Address(rdx_intf, java_mirror_offset));  // required interface
-      __ push(rcx_recv);        // bad receiver
-      __ push((int)Bytecodes::_invokeinterface);  // who is complaining?
+      __ mov(rbx_temp, rcx_recv);  // rarg2_required might be RCX
+      assert_different_registers(rarg2_required, rbx_temp);
+      __ movptr(rarg2_required, Address(rdx_intf, java_mirror_offset));  // required interface
+      __ mov(   rarg1_actual,   rbx_temp);                               // bad receiver
+      __ movl(  rarg0_code,     (int) Bytecodes::_invokeinterface);      // who is complaining?
       __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
     }
     break;
@@ -669,10 +675,10 @@
       __ movl(rax_argslot, rcx_amh_vmargslot);  // reload argslot field
       __ movptr(rdx_temp, vmarg);
 
-      __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class
-      __ push(rbx_klass);
-      __ push(rdx_temp);                             // bad object
-      __ push((int)Bytecodes::_checkcast);           // who is complaining?
+      assert_different_registers(rarg2_required, rdx_temp);
+      __ load_heap_oop(rarg2_required, rcx_amh_argument);             // required class
+      __ mov(          rarg1_actual,   rdx_temp);                     // bad object
+      __ movl(         rarg0_code,     (int) Bytecodes::_checkcast);  // who is complaining?
       __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
 
       __ bind(done);
@@ -1189,16 +1195,18 @@
 
       __ bind(bad_array_klass);
       UNPUSH_RSI_RDI;
-      __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type
-      __ pushptr(vmarg);                // bad array
-      __ push((int)Bytecodes::_aaload); // who is complaining?
+      assert(!vmarg.uses(rarg2_required), "must be different registers");
+      __ movptr(rarg2_required, Address(rdx_array_klass, java_mirror_offset));  // required type
+      __ movptr(rarg1_actual,   vmarg);                                         // bad array
+      __ movl(  rarg0_code,     (int) Bytecodes::_aaload);                      // who is complaining?
       __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
 
       __ bind(bad_array_length);
       UNPUSH_RSI_RDI;
-      __ push(rcx_recv);        // AMH requiring a certain length
-      __ pushptr(vmarg);        // bad array
-      __ push((int)Bytecodes::_arraylength); // who is complaining?
+      assert(!vmarg.uses(rarg2_required), "must be different registers");
+      __ mov   (rarg2_required, rcx_recv);                       // AMH requiring a certain length
+      __ movptr(rarg1_actual,   vmarg);                          // bad array
+      __ movl(  rarg0_code,     (int) Bytecodes::_arraylength);  // who is complaining?
       __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
 
 #undef UNPUSH_RSI_RDI
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3203,10 +3203,12 @@
   const bool allow_shared_alloc =
     Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode;
 
+  const Register thread = rcx;
+  if (UseTLAB || allow_shared_alloc) {
+    __ get_thread(thread);
+  }
+
   if (UseTLAB) {
-    const Register thread = rcx;
-
-    __ get_thread(thread);
     __ movptr(rax, Address(thread, in_bytes(JavaThread::tlab_top_offset())));
     __ lea(rbx, Address(rax, rdx, Address::times_1));
     __ cmpptr(rbx, Address(thread, in_bytes(JavaThread::tlab_end_offset())));
@@ -3247,6 +3249,8 @@
 
     // if someone beat us on the allocation, try again, otherwise continue
     __ jcc(Assembler::notEqual, retry);
+
+    __ incr_allocated_bytes(thread, rdx, 0);
   }
 
   if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
@@ -3256,12 +3260,12 @@
     __ decrement(rdx, sizeof(oopDesc));
     __ jcc(Assembler::zero, initialize_header);
 
-  // Initialize topmost object field, divide rdx by 8, check if odd and
-  // test if zero.
+    // Initialize topmost object field, divide rdx by 8, check if odd and
+    // test if zero.
     __ xorl(rcx, rcx);    // use zero reg to clear memory (shorter code)
     __ shrl(rdx, LogBytesPerLong); // divide by 2*oopSize and set carry flag if odd
 
-  // rdx must have been multiple of 8
+    // rdx must have been multiple of 8
 #ifdef ASSERT
     // make sure rdx was multiple of 8
     Label L;
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3266,6 +3266,8 @@
 
     // if someone beat us on the allocation, try again, otherwise continue
     __ jcc(Assembler::notEqual, retry);
+
+    __ incr_allocated_bytes(r15_thread, rdx, 0);
   }
 
   if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -635,7 +635,29 @@
     return -1;
   }
 
-  return fd;
+  // Verify that we have enough disk space for this file.
+  // We'll get random SIGBUS crashes on memory accesses if
+  // we don't.
+
+  for (size_t seekpos = 0; seekpos < size; seekpos += os::vm_page_size()) {
+    int zero_int = 0;
+    result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos));
+    if (result == -1 ) break;
+    RESTARTABLE(::write(fd, &zero_int, 1), result);
+    if (result != 1) {
+      if (errno == ENOSPC) {
+        warning("Insufficient space for shared memory file:\n   %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename);
+      }
+      break;
+    }
+  }
+
+  if (result != -1) {
+    return fd;
+  } else {
+    RESTARTABLE(::close(fd), result);
+    return -1;
+  }
 }
 
 // open the shared memory file for the given user and vmid. returns
--- a/hotspot/src/os/posix/launcher/java_md.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/posix/launcher/java_md.c	Wed Jan 19 19:00:30 2011 -0800
@@ -28,7 +28,6 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 #include <inttypes.h>
-#include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -80,6 +80,7 @@
 // put OS-includes here
 # include <dlfcn.h>
 # include <errno.h>
+# include <exception>
 # include <link.h>
 # include <poll.h>
 # include <pthread.h>
@@ -282,7 +283,7 @@
                is_error_reported(),
               "sp must be inside of selected thread stack");
 
-    thread->_self_raw_id = raw_id;  // mark for quick retrieval
+    thread->set_self_raw_id(raw_id);  // mark for quick retrieval
     _get_thread_cache[ index ] = thread;
   }
   return thread;
@@ -1475,6 +1476,13 @@
   return &allowdebug_blocked_sigs;
 }
 
+
+void _handle_uncaught_cxx_exception() {
+  VMError err("An uncaught C++ exception");
+  err.report_and_die();
+}
+
+
 // First crack at OS-specific initialization, from inside the new thread.
 void os::initialize_thread() {
   int r = thr_main() ;
@@ -1564,6 +1572,7 @@
    // use the dynamic check for T2 libthread.
 
   os::Solaris::init_thread_fpu_state();
+  std::set_terminate(_handle_uncaught_cxx_exception);
 }
 
 
@@ -3081,7 +3090,7 @@
     if (addr == NULL) {
       jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
     }
-    warning("attempt_reserve_memory_at: couldn't reserve %d bytes at "
+    warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
             PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
             "%s", bytes, requested_addr, addr, buf);
   }
@@ -5188,7 +5197,7 @@
   int o_delete = (oflag & O_DELETE);
   oflag = oflag & ~O_DELETE;
 
-  fd = ::open(path, oflag, mode);
+  fd = ::open64(path, oflag, mode);
   if (fd == -1) return -1;
 
   //If the open succeeded, the file might still be a directory
--- a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,10 +53,10 @@
 
   uintptr_t raw = pd_raw_thread_id();
   int ix = pd_cache_index(raw);
-  Thread *Candidate = ThreadLocalStorage::_get_thread_cache[ix];
-  if (Candidate->_self_raw_id == raw) {
+  Thread* candidate = ThreadLocalStorage::_get_thread_cache[ix];
+  if (candidate->self_raw_id() == raw) {
     // hit
-    return Candidate;
+    return candidate;
   } else {
     return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix);
   }
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * CopyrighT (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2004,6 +2004,16 @@
   int   number;
 };
 
+// All Visual C++ exceptions thrown from code generated by the Microsoft Visual
+// C++ compiler contain this error code. Because this is a compiler-generated
+// error, the code is not listed in the Win32 API header files.
+// The code is actually a cryptic mnemonic device, with the initial "E"
+// standing for "exception" and the final 3 bytes (0x6D7363) representing the
+// ASCII values of "msc".
+
+#define EXCEPTION_UNCAUGHT_CXX_EXCEPTION    0xE06D7363
+
+
 struct siglabel exceptlabels[] = {
     def_excpt(EXCEPTION_ACCESS_VIOLATION),
     def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
@@ -2028,6 +2038,7 @@
     def_excpt(EXCEPTION_INVALID_DISPOSITION),
     def_excpt(EXCEPTION_GUARD_PAGE),
     def_excpt(EXCEPTION_INVALID_HANDLE),
+    def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
     NULL, 0
 };
 
@@ -2261,7 +2272,6 @@
     }
   }
 
-
   if (t != NULL && t->is_Java_thread()) {
     JavaThread* thread = (JavaThread*) t;
     bool in_java = thread->thread_state() == _thread_in_Java;
@@ -2465,8 +2475,9 @@
       } // switch
     }
 #ifndef _WIN64
-    if ((thread->thread_state() == _thread_in_Java) ||
-        (thread->thread_state() == _thread_in_native) )
+    if (((thread->thread_state() == _thread_in_Java) ||
+        (thread->thread_state() == _thread_in_native)) &&
+        exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION)
     {
       LONG result=Handle_FLT_Exception(exceptionInfo);
       if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
@@ -2490,6 +2501,7 @@
       case EXCEPTION_ILLEGAL_INSTRUCTION_2:
       case EXCEPTION_INT_OVERFLOW:
       case EXCEPTION_INT_DIVIDE_BY_ZERO:
+      case EXCEPTION_UNCAUGHT_CXX_EXCEPTION:
       {  report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                        exceptionInfo->ContextRecord);
       }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -585,6 +585,13 @@
   sigaddset(&newset, sig);
   sigprocmask(SIG_UNBLOCK, &newset, NULL);
 
+  // Determine which sort of error to throw.  Out of swap may signal
+  // on the thread stack, which could get a mapping error when touched.
+  address addr = (address) info->si_addr;
+  if (sig == SIGBUS && info->si_code == BUS_OBJERR && info->si_errno == ENOMEM) {
+    vm_exit_out_of_memory(0, "Out of swap space to map in thread stack.");
+  }
+
   VMError err(t, sig, pc, info, ucVoid);
   err.report_and_die();
 
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -29,6 +29,7 @@
 # include <sys/auxv.h>
 # include <sys/auxv_SPARC.h>
 # include <sys/systeminfo.h>
+# include <kstat.h>
 
 // We need to keep these here as long as we have to build on Solaris
 // versions before 10.
@@ -96,11 +97,23 @@
 #ifndef AV_SPARC_ASI_BLK_INIT
 #define AV_SPARC_ASI_BLK_INIT 0x0080  /* ASI_BLK_INIT_xxx ASI */
 #endif
+    if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
+
 #ifndef AV_SPARC_FMAF
-#define AV_SPARC_FMAF 0x0100  /* Sparc64 Fused Multiply-Add */
+#define AV_SPARC_FMAF 0x0100        /* Fused Multiply-Add */
 #endif
-    if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
     if (av & AV_SPARC_FMAF)         features |= fmaf_instructions_m;
+
+#ifndef AV_SPARC_FMAU
+#define    AV_SPARC_FMAU    0x0200  /* Unfused Multiply-Add */
+#endif
+    if (av & AV_SPARC_FMAU)         features |= fmau_instructions_m;
+
+#ifndef AV_SPARC_VIS3
+#define    AV_SPARC_VIS3    0x0400  /* VIS3 instruction set extensions */
+#endif
+    if (av & AV_SPARC_VIS3)         features |= vis3_instructions_m;
+
   } else {
     // getisax(2) failed, use the old legacy code.
 #ifndef PRODUCT
@@ -140,5 +153,59 @@
   // Determine the machine type.
   do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);
 
+  {
+    // Using kstat to determine the machine type.
+    kstat_ctl_t* kc = kstat_open();
+    kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
+    const char* implementation = "UNKNOWN";
+    if (ksp != NULL) {
+      if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
+        kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
+        for (int i = 0; i < ksp->ks_ndata; i++) {
+          if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
+#ifndef KSTAT_DATA_STRING
+#define KSTAT_DATA_STRING   9
+#endif
+            if (knm[i].data_type == KSTAT_DATA_CHAR) {
+              // VM is running on Solaris 8 which does not have value.str.
+              implementation = &(knm[i].value.c[0]);
+            } else if (knm[i].data_type == KSTAT_DATA_STRING) {
+              // VM is running on Solaris 10.
+#ifndef KSTAT_NAMED_STR_PTR
+              // Solaris 8 was used to build VM, define the structure it misses.
+              struct str_t {
+                union {
+                  char *ptr;     /* NULL-term string */
+                  char __pad[8]; /* 64-bit padding */
+                } addr;
+                uint32_t len;    /* # bytes for strlen + '\0' */
+              };
+#define KSTAT_NAMED_STR_PTR(knptr) (( (str_t*)&((knptr)->value) )->addr.ptr)
+#endif
+              implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
+            }
+#ifndef PRODUCT
+            if (PrintMiscellaneous && Verbose) {
+              tty->print_cr("cpu_info.implementation: %s", implementation);
+            }
+#endif
+            if (strncmp(implementation, "SPARC64", 7) == 0) {
+              features |= sparc64_family_m;
+            } else if (strncmp(implementation, "UltraSPARC-T", 12) == 0) {
+              features |= T_family_m;
+              if (strncmp(implementation, "UltraSPARC-T1", 13) == 0) {
+                features |= T1_model_m;
+              }
+            }
+            break;
+          }
+        } // for(
+      }
+    }
+    assert(strcmp(implementation, "UNKNOWN") != 0,
+           "unknown cpu info (changed kstat interface?)");
+    kstat_close(kc);
+  }
+
   return features;
 }
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -742,6 +742,13 @@
   sigaddset(&newset, sig);
   sigprocmask(SIG_UNBLOCK, &newset, NULL);
 
+  // Determine which sort of error to throw.  Out of swap may signal
+  // on the thread stack, which could get a mapping error when touched.
+  address addr = (address) info->si_addr;
+  if (sig == SIGBUS && info->si_code == BUS_OBJERR && info->si_errno == ENOMEM) {
+    vm_exit_out_of_memory(0, "Out of swap space to map in thread stack.");
+  }
+
   VMError err(t, sig, pc, info, ucVoid);
   err.report_and_die();
 
--- a/hotspot/src/share/vm/adlc/dict2.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/adlc/dict2.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -34,7 +34,7 @@
 #define MAXID 20
 static char initflag = 0;       // True after 1st initialization
 static char shft[MAXID] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6};
-static short xsum[MAXID + 1];
+static short xsum[MAXID];
 
 //------------------------------bucket---------------------------------------
 class bucket {
@@ -66,7 +66,7 @@
   // Precompute table of null character hashes
   if( !initflag ) {             // Not initializated yet?
     xsum[0] = (1<<shft[0])+1;   // Initialize
-    for( i = 1; i < MAXID + 1; i++) {
+    for( i = 1; i < MAXID; i++) {
       xsum[i] = (1<<shft[i])+1+xsum[i-1];
     }
     initflag = 1;               // Never again
@@ -291,7 +291,7 @@
     c = (c<<1)+1;               // Characters are always odd!
     sum += c + (c<<shft[k++]);  // Universal hash function
   }
-  assert( k < (MAXID + 1), "Exceeded maximum name length");
+  assert( k < (MAXID), "Exceeded maximum name length");
   return (int)((sum+xsum[k]) >> 1); // Hash key, un-modulo'd table size
 }
 
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -245,7 +245,7 @@
 }
 
 
-void Compilation::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) {
+bool Compilation::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) {
   // Preinitialize the consts section to some large size:
   int locs_buffer_size = 20 * (relocInfo::length_limit + sizeof(relocInfo));
   char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
@@ -253,15 +253,20 @@
                                         locs_buffer_size / sizeof(relocInfo));
   code->initialize_consts_size(Compilation::desired_max_constant_size());
   // Call stubs + two deopt handlers (regular and MH) + exception handler
-  code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) +
-                              LIR_Assembler::exception_handler_size +
-                              2 * LIR_Assembler::deopt_handler_size);
+  int stub_size = (call_stub_estimate * LIR_Assembler::call_stub_size) +
+                   LIR_Assembler::exception_handler_size +
+                   (2 * LIR_Assembler::deopt_handler_size);
+  if (stub_size >= code->insts_capacity()) return false;
+  code->initialize_stubs_size(stub_size);
+  return true;
 }
 
 
 int Compilation::emit_code_body() {
   // emit code
-  setup_code_buffer(code(), allocator()->num_calls());
+  if (!setup_code_buffer(code(), allocator()->num_calls())) {
+    BAILOUT_("size requested greater than avail code buffer size", 0);
+  }
   code()->initialize_oop_recorder(env()->oop_recorder());
 
   _masm = new C1_MacroAssembler(code());
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -192,7 +192,7 @@
     return desired_max_code_buffer_size() / 10;
   }
 
-  static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
+  static bool setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
 
   // timers
   static void print_timers();
--- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -92,7 +92,7 @@
     if (opr->is_address()) {
       LIR_Address* addr = opr->as_address_ptr();
       assert(addr->disp() == (int)addr->disp(), "out of range value");
-      out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4);
+      out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);
     }
     i += type2size[t];
   }
@@ -143,7 +143,7 @@
     args->append(opr);
     if (opr->is_address()) {
       LIR_Address* addr = opr->as_address_ptr();
-      out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4);
+      out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);
     }
     i += type2size[t];
   }
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1568,15 +1568,16 @@
     assert(code == lir_cmp, "code check");
   }
 
-  LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result)
+  LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type)
     : LIR_Op(code, result, NULL)
     , _opr1(opr1)
     , _opr2(opr2)
-    , _type(T_ILLEGAL)
+    , _type(type)
     , _condition(condition)
     , _fpu_stack_size(0)
     , _tmp(LIR_OprFact::illegalOpr) {
     assert(code == lir_cmove, "code check");
+    assert(type != T_ILLEGAL, "cmove should have type");
   }
 
   LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result = LIR_OprFact::illegalOpr,
@@ -1993,8 +1994,8 @@
   void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info);
   void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Address* addr, CodeEmitInfo* info);
 
-  void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst) {
-    append(new LIR_Op2(lir_cmove, condition, src1, src2, dst));
+  void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type) {
+    append(new LIR_Op2(lir_cmove, condition, src1, src2, dst, type));
   }
 
   void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -685,7 +685,7 @@
       break;
 
     case lir_cmove:
-      cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr());
+      cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type());
       break;
 
     case lir_shl:
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -217,7 +217,7 @@
   void volatile_move_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info);
   void comp_mem_op(LIR_Opr src, LIR_Opr result, BasicType type, CodeEmitInfo* info);  // info set for null exceptions
   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 cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result, BasicType type);
 
   void call(        LIR_OpJavaCall* op, relocInfo::relocType rtype);
   void ic_call(     LIR_OpJavaCall* op);
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -856,7 +856,7 @@
     __ cmove(lir_cond(cond),
              LIR_OprFact::intptrConst(taken_count_offset),
              LIR_OprFact::intptrConst(not_taken_count_offset),
-             data_offset_reg);
+             data_offset_reg, as_BasicType(if_instr->x()->type()));
 
     // MDO cells are intptr_t, so the data_reg width is arch-dependent.
     LIR_Opr data_reg = new_pointer_register();
@@ -2591,7 +2591,7 @@
   LIR_Opr reg = rlock_result(x);
 
   __ cmp(lir_cond(x->cond()), left.result(), right.result());
-  __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg);
+  __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type()));
 }
 
 
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -90,6 +90,7 @@
  , _intervals(0)   // initialized later with correct length
  , _new_intervals_from_allocation(new IntervalList())
  , _sorted_intervals(NULL)
+ , _needs_full_resort(false)
  , _lir_ops(0)     // initialized later with correct length
  , _block_of_op(0) // initialized later with correct length
  , _has_info(0)
@@ -1520,6 +1521,14 @@
 void LinearScan::sort_intervals_before_allocation() {
   TIME_LINEAR_SCAN(timer_sort_intervals_before);
 
+  if (_needs_full_resort) {
+    // There is no known reason why this should occur but just in case...
+    assert(false, "should never occur");
+    // Re-sort existing interval list because an Interval::from() has changed
+    _sorted_intervals->sort(interval_cmp);
+    _needs_full_resort = false;
+  }
+
   IntervalList* unsorted_list = &_intervals;
   int unsorted_len = unsorted_list->length();
   int sorted_len = 0;
@@ -1559,11 +1568,18 @@
     }
   }
   _sorted_intervals = sorted_list;
+  assert(is_sorted(_sorted_intervals), "intervals unsorted");
 }
 
 void LinearScan::sort_intervals_after_allocation() {
   TIME_LINEAR_SCAN(timer_sort_intervals_after);
 
+  if (_needs_full_resort) {
+    // Re-sort existing interval list because an Interval::from() has changed
+    _sorted_intervals->sort(interval_cmp);
+    _needs_full_resort = false;
+  }
+
   IntervalArray* old_list      = _sorted_intervals;
   IntervalList*  new_list      = _new_intervals_from_allocation;
   int old_len = old_list->length();
@@ -1571,6 +1587,7 @@
 
   if (new_len == 0) {
     // no intervals have been added during allocation, so sorted list is already up to date
+    assert(is_sorted(_sorted_intervals), "intervals unsorted");
     return;
   }
 
@@ -1593,6 +1610,7 @@
   }
 
   _sorted_intervals = combined_list;
+  assert(is_sorted(_sorted_intervals), "intervals unsorted");
 }
 
 
@@ -1825,6 +1843,8 @@
       interval = interval->split(from_op_id);
       interval->assign_reg(reg, regHi);
       append_interval(interval);
+    } else {
+      _needs_full_resort = true;
     }
     assert(interval->from() == from_op_id, "must be true now");
 
@@ -4492,7 +4512,8 @@
     }
   } else {
     type_name = type2name(type());
-    if (assigned_reg() != -1) {
+    if (assigned_reg() != -1 &&
+        (LinearScan::num_physical_regs(type()) == 1 || assigned_regHi() != -1)) {
       opr = LinearScan::calc_operand_for_interval(this);
     }
   }
--- a/hotspot/src/share/vm/c1/c1_LinearScan.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -148,6 +148,7 @@
   IntervalList              _intervals;         // mapping from register number to interval
   IntervalList*             _new_intervals_from_allocation; // list with all intervals created during allocation when an existing interval is split
   IntervalArray*            _sorted_intervals;  // intervals sorted by Interval::from()
+  bool                      _needs_full_resort; // set to true if an Interval::from() is changed and _sorted_intervals must be resorted
 
   LIR_OpArray               _lir_ops;           // mapping from LIR_Op id to LIR_Op node
   BlockBeginArray           _block_of_op;       // mapping from LIR_Op id to the BlockBegin containing this instruction
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -2386,19 +2386,21 @@
       valid_cp_range(bootstrap_method_index, cp_size) &&
       cp->tag_at(bootstrap_method_index).is_method_handle(),
       "bootstrap_method_index %u has bad constant type in class file %s",
+      bootstrap_method_index,
       CHECK);
     operands->short_at_put(operand_fill_index++, bootstrap_method_index);
     operands->short_at_put(operand_fill_index++, argument_count);
 
     cfs->guarantee_more(sizeof(u2) * argument_count, CHECK);  // argv[argc]
     for (int j = 0; j < argument_count; j++) {
-      u2 arg_index = cfs->get_u2_fast();
+      u2 argument_index = cfs->get_u2_fast();
       check_property(
-        valid_cp_range(arg_index, cp_size) &&
-        cp->tag_at(arg_index).is_loadable_constant(),
+        valid_cp_range(argument_index, cp_size) &&
+        cp->tag_at(argument_index).is_loadable_constant(),
         "argument_index %u has bad constant type in class file %s",
+        argument_index,
         CHECK);
-      operands->short_at_put(operand_fill_index++, arg_index);
+      operands->short_at_put(operand_fill_index++, argument_index);
     }
   }
 
--- a/hotspot/src/share/vm/code/codeCache.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -939,7 +939,9 @@
                _heap->high(),
                _heap->high_boundary());
   st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
-               " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT,
+               " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT
+               " largest_free_block=" SIZE_FORMAT,
                CodeCache::nof_blobs(), CodeCache::nof_nmethods(),
-               CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
+               CodeCache::nof_adapters(), CodeCache::unallocated_capacity(),
+               CodeCache::largest_free_block());
 }
--- a/hotspot/src/share/vm/code/codeCache.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -158,6 +158,7 @@
   static size_t  capacity()                      { return _heap->capacity(); }
   static size_t  max_capacity()                  { return _heap->max_capacity(); }
   static size_t  unallocated_capacity()          { return _heap->unallocated_capacity(); }
+  static size_t  largest_free_block()            { return _heap->largest_free_block(); }
   static bool    needs_flushing()                { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
 
   static bool needs_cache_clean()                { return _needs_cache_clean; }
--- a/hotspot/src/share/vm/code/nmethod.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -811,9 +811,11 @@
     _stub_offset             = content_offset()      + code_buffer->total_offset_of(code_buffer->stubs());
 
     // Exception handler and deopt handler are in the stub section
+    assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
+    assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
     _exception_offset        = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
     _deoptimize_offset       = _stub_offset          + offsets->value(CodeOffsets::Deopt);
-    if (has_method_handle_invokes()) {
+    if (offsets->value(CodeOffsets::DeoptMH) != -1) {
       _deoptimize_mh_offset  = _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
     } else {
       _deoptimize_mh_offset  = -1;
@@ -1909,6 +1911,7 @@
       break;
     }
   }
+  assert(has_method_handle_invokes() == (_deoptimize_mh_offset != -1), "must have deopt mh handler");
 
   int size = count * sizeof(PcDesc);
   assert(scopes_pcs_size() >= size, "oob");
--- a/hotspot/src/share/vm/compiler/abstractCompiler.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -33,6 +33,7 @@
     bool do_initialization = false;
     {
       ThreadInVMfromNative tv(thread);
+      ResetNoHandleMark rnhm;
       MutexLocker only_one(CompileThread_lock, thread);
       if ( *state == uninitialized) {
         do_initialization = true;
@@ -53,6 +54,7 @@
       // To in_vm so we can use the lock
 
       ThreadInVMfromNative tv(thread);
+      ResetNoHandleMark rnhm;
       MutexLocker only_one(CompileThread_lock, thread);
       assert(*state == initializing, "wrong state");
       *state = initialized;
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -332,7 +332,7 @@
          "command_names size mismatch");
 
   *bytes_read = 0;
-  char command[32];
+  char command[33];
   int result = sscanf(line, "%32[a-z]%n", command, bytes_read);
   for (uint i = 0; i < ARRAY_SIZE(command_names); i++) {
     if (strcmp(command, command_names[i]) == 0) {
@@ -470,6 +470,12 @@
   OracleCommand command = parse_command_name(line, &bytes_read);
   line += bytes_read;
 
+  if (command == UnknownCommand) {
+    tty->print_cr("CompilerOracle: unrecognized line");
+    tty->print_cr("  \"%s\"", original_line);
+    return;
+  }
+
   if (command == QuietCommand) {
     _quiet = true;
     return;
@@ -498,7 +504,7 @@
     line += bytes_read;
     // there might be a signature following the method.
     // signatures always begin with ( so match that by hand
-    if (1 == sscanf(line, "%*[ \t](%254[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
+    if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
       sig[0] = '(';
       line += bytes_read;
       signature = oopFactory::new_symbol_handle(sig, CHECK);
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -153,6 +153,7 @@
       check_for_non_bad_heap_word_value(result, size));
     assert(!HAS_PENDING_EXCEPTION,
            "Unexpected exception, will result in uninitialized storage");
+    THREAD->incr_allocated_bytes(size * HeapWordSize);
     return result;
   }
 
--- a/hotspot/src/share/vm/memory/heap.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/heap.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -315,6 +315,15 @@
   return l;
 }
 
+size_t CodeHeap::largest_free_block() const {
+  size_t len = 0;
+  for (FreeBlock* b = _freelist; b != NULL; b = b->link()) {
+    if (b->length() > len)
+      len = b->length();
+  }
+  return size(len);
+}
+
 // Free list management
 
 FreeBlock *CodeHeap::following_block(FreeBlock *b) {
--- a/hotspot/src/share/vm/memory/heap.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/heap.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -161,6 +161,7 @@
   size_t max_capacity() const;
   size_t allocated_capacity() const;
   size_t unallocated_capacity() const            { return max_capacity() - allocated_capacity(); }
+  size_t largest_free_block() const;
 
   // Debugging
   void verify();
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,6 +114,11 @@
 void ThreadLocalAllocBuffer::make_parsable(bool retire) {
   if (end() != NULL) {
     invariants();
+
+    if (retire) {
+      myThread()->incr_allocated_bytes(used_bytes());
+    }
+
     CollectedHeap::fill_with_object(top(), hard_end(), retire);
 
     if (retire || ZeroTLAB) {  // "Reset" the TLAB
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -112,6 +112,8 @@
   HeapWord* top() const                          { return _top; }
   HeapWord* pf_top() const                       { return _pf_top; }
   size_t desired_size() const                    { return _desired_size; }
+  size_t used() const                            { return pointer_delta(top(), start()); }
+  size_t used_bytes() const                      { return pointer_delta(top(), start(), 1); }
   size_t free() const                            { return pointer_delta(end(), top()); }
   // Don't discard tlab if remaining space is larger than this.
   size_t refill_waste_limit() const              { return _refill_waste_limit; }
--- a/hotspot/src/share/vm/memory/universe.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/memory/universe.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -934,7 +934,8 @@
     // See needs_explicit_null_check.
     // Only set the heap base for compressed oops because it indicates
     // compressed oops for pstack code.
-    if (PrintCompressedOopsMode) {
+    bool verbose = PrintCompressedOopsMode || (PrintMiscellaneous && Verbose);
+    if (verbose) {
       tty->cr();
       tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
                  Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
@@ -943,12 +944,12 @@
       // Can't reserve heap below 32Gb.
       Universe::set_narrow_oop_base(Universe::heap()->base() - os::vm_page_size());
       Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
-      if (PrintCompressedOopsMode) {
+      if (verbose) {
         tty->print(", Compressed Oops with base: "PTR_FORMAT, Universe::narrow_oop_base());
       }
     } else {
       Universe::set_narrow_oop_base(0);
-      if (PrintCompressedOopsMode) {
+      if (verbose) {
         tty->print(", zero based Compressed Oops");
       }
 #ifdef _WIN64
@@ -963,12 +964,12 @@
         Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
       } else {
         Universe::set_narrow_oop_shift(0);
-        if (PrintCompressedOopsMode) {
+        if (verbose) {
           tty->print(", 32-bits Oops");
         }
       }
     }
-    if (PrintCompressedOopsMode) {
+    if (verbose) {
       tty->cr();
       tty->cr();
     }
--- a/hotspot/src/share/vm/opto/compile.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -444,22 +444,32 @@
 }
 
 
+//-----------------------init_scratch_buffer_blob------------------------------
+// Construct a temporary BufferBlob and cache it for this compile.
 void Compile::init_scratch_buffer_blob(int const_size) {
-  if (scratch_buffer_blob() != NULL)  return;
+  // If there is already a scratch buffer blob allocated and the
+  // constant section is big enough, use it.  Otherwise free the
+  // current and allocate a new one.
+  BufferBlob* blob = scratch_buffer_blob();
+  if ((blob != NULL) && (const_size <= _scratch_const_size)) {
+    // Use the current blob.
+  } else {
+    if (blob != NULL) {
+      BufferBlob::free(blob);
+    }
 
-  // Construct a temporary CodeBuffer to have it construct a BufferBlob
-  // Cache this BufferBlob for this compile.
-  ResourceMark rm;
-  _scratch_const_size = const_size;
-  int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size);
-  BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size);
-  // Record the buffer blob for next time.
-  set_scratch_buffer_blob(blob);
-  // Have we run out of code space?
-  if (scratch_buffer_blob() == NULL) {
-    // Let CompilerBroker disable further compilations.
-    record_failure("Not enough space for scratch buffer in CodeCache");
-    return;
+    ResourceMark rm;
+    _scratch_const_size = const_size;
+    int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size);
+    blob = BufferBlob::create("Compile::scratch_buffer", size);
+    // Record the buffer blob for next time.
+    set_scratch_buffer_blob(blob);
+    // Have we run out of code space?
+    if (scratch_buffer_blob() == NULL) {
+      // Let CompilerBroker disable further compilations.
+      record_failure("Not enough space for scratch buffer in CodeCache");
+      return;
+    }
   }
 
   // Initialize the relocation buffers
@@ -468,13 +478,6 @@
 }
 
 
-void Compile::clear_scratch_buffer_blob() {
-  assert(scratch_buffer_blob(), "no BufferBlob set");
-  set_scratch_buffer_blob(NULL);
-  set_scratch_locs_memory(NULL);
-}
-
-
 //-----------------------scratch_emit_size-------------------------------------
 // Helper function that computes size by emitting code
 uint Compile::scratch_emit_size(const Node* n) {
--- a/hotspot/src/share/vm/opto/escape.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/escape.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1609,10 +1609,11 @@
   //
   // Normally only 1-3 passes needed to build
   // Connection Graph depending on graph complexity.
-  // Set limit to 10 to catch situation when something
+  // Observed 8 passes in jvm2008 compiler.compiler.
+  // Set limit to 20 to catch situation when something
   // did go wrong and recompile the method without EA.
 
-#define CG_BUILD_ITER_LIMIT 10
+#define CG_BUILD_ITER_LIMIT 20
 
   uint length = worklist.length();
   int iterations = 0;
--- a/hotspot/src/share/vm/opto/macro.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/macro.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1158,7 +1158,7 @@
     // Note: We set the control input on "eden_end" and "old_eden_top" when using
     //       a TLAB to work around a bug where these values were being moved across
     //       a safepoint.  These are not oops, so they cannot be include in the oop
-    //       map, but the can be changed by a GC.   The proper way to fix this would
+    //       map, but they can be changed by a GC.   The proper way to fix this would
     //       be to set the raw memory state when generating a  SafepointNode.  However
     //       this will require extensive changes to the loop optimization in order to
     //       prevent a degradation of the optimization.
@@ -1167,24 +1167,24 @@
 
     // allocate the Region and Phi nodes for the result
     result_region = new (C, 3) RegionNode(3);
-    result_phi_rawmem = new (C, 3) PhiNode( result_region, Type::MEMORY, TypeRawPtr::BOTTOM );
-    result_phi_rawoop = new (C, 3) PhiNode( result_region, TypeRawPtr::BOTTOM );
-    result_phi_i_o    = new (C, 3) PhiNode( result_region, Type::ABIO ); // I/O is used for Prefetch
+    result_phi_rawmem = new (C, 3) PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    result_phi_rawoop = new (C, 3) PhiNode(result_region, TypeRawPtr::BOTTOM);
+    result_phi_i_o    = new (C, 3) PhiNode(result_region, Type::ABIO); // I/O is used for Prefetch
 
     // We need a Region for the loop-back contended case.
     enum { fall_in_path = 1, contended_loopback_path = 2 };
     Node *contended_region;
     Node *contended_phi_rawmem;
-    if( UseTLAB ) {
+    if (UseTLAB) {
       contended_region = toobig_false;
       contended_phi_rawmem = mem;
     } else {
       contended_region = new (C, 3) RegionNode(3);
-      contended_phi_rawmem = new (C, 3) PhiNode( contended_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+      contended_phi_rawmem = new (C, 3) PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM);
       // Now handle the passing-too-big test.  We fall into the contended
       // loop-back merge point.
-      contended_region    ->init_req( fall_in_path, toobig_false );
-      contended_phi_rawmem->init_req( fall_in_path, mem );
+      contended_region    ->init_req(fall_in_path, toobig_false);
+      contended_phi_rawmem->init_req(fall_in_path, mem);
       transform_later(contended_region);
       transform_later(contended_phi_rawmem);
     }
@@ -1192,78 +1192,101 @@
     // Load(-locked) the heap top.
     // See note above concerning the control input when using a TLAB
     Node *old_eden_top = UseTLAB
-      ? new (C, 3) LoadPNode     ( ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM )
-      : new (C, 3) LoadPLockedNode( contended_region, contended_phi_rawmem, eden_top_adr );
+      ? new (C, 3) LoadPNode      (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM)
+      : new (C, 3) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr);
 
     transform_later(old_eden_top);
     // Add to heap top to get a new heap top
-    Node *new_eden_top = new (C, 4) AddPNode( top(), old_eden_top, size_in_bytes );
+    Node *new_eden_top = new (C, 4) AddPNode(top(), old_eden_top, size_in_bytes);
     transform_later(new_eden_top);
     // Check for needing a GC; compare against heap end
-    Node *needgc_cmp = new (C, 3) CmpPNode( new_eden_top, eden_end );
+    Node *needgc_cmp = new (C, 3) CmpPNode(new_eden_top, eden_end);
     transform_later(needgc_cmp);
-    Node *needgc_bol = new (C, 2) BoolNode( needgc_cmp, BoolTest::ge );
+    Node *needgc_bol = new (C, 2) BoolNode(needgc_cmp, BoolTest::ge);
     transform_later(needgc_bol);
-    IfNode *needgc_iff = new (C, 2) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN );
+    IfNode *needgc_iff = new (C, 2) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN);
     transform_later(needgc_iff);
 
     // Plug the failing-heap-space-need-gc test into the slow-path region
-    Node *needgc_true = new (C, 1) IfTrueNode( needgc_iff );
+    Node *needgc_true = new (C, 1) IfTrueNode(needgc_iff);
     transform_later(needgc_true);
-    if( initial_slow_test ) {
-      slow_region    ->init_req( need_gc_path, needgc_true );
+    if (initial_slow_test) {
+      slow_region->init_req(need_gc_path, needgc_true);
       // This completes all paths into the slow merge point
       transform_later(slow_region);
     } else {                      // No initial slow path needed!
       // Just fall from the need-GC path straight into the VM call.
-      slow_region    = needgc_true;
+      slow_region = needgc_true;
     }
     // No need for a GC.  Setup for the Store-Conditional
-    Node *needgc_false = new (C, 1) IfFalseNode( needgc_iff );
+    Node *needgc_false = new (C, 1) IfFalseNode(needgc_iff);
     transform_later(needgc_false);
 
     // Grab regular I/O before optional prefetch may change it.
     // Slow-path does no I/O so just set it to the original I/O.
-    result_phi_i_o->init_req( slow_result_path, i_o );
+    result_phi_i_o->init_req(slow_result_path, i_o);
 
     i_o = prefetch_allocation(i_o, needgc_false, contended_phi_rawmem,
                               old_eden_top, new_eden_top, length);
 
+    // Name successful fast-path variables
+    Node* fast_oop = old_eden_top;
+    Node* fast_oop_ctrl;
+    Node* fast_oop_rawmem;
+
     // Store (-conditional) the modified eden top back down.
     // StorePConditional produces flags for a test PLUS a modified raw
     // memory state.
-    Node *store_eden_top;
-    Node *fast_oop_ctrl;
-    if( UseTLAB ) {
-      store_eden_top = new (C, 4) StorePNode( needgc_false, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, new_eden_top );
+    if (UseTLAB) {
+      Node* store_eden_top =
+        new (C, 4) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr,
+                              TypeRawPtr::BOTTOM, new_eden_top);
       transform_later(store_eden_top);
       fast_oop_ctrl = needgc_false; // No contention, so this is the fast path
+      fast_oop_rawmem = store_eden_top;
     } else {
-      store_eden_top = new (C, 5) StorePConditionalNode( needgc_false, contended_phi_rawmem, eden_top_adr, new_eden_top, old_eden_top );
+      Node* store_eden_top =
+        new (C, 5) StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr,
+                                         new_eden_top, fast_oop/*old_eden_top*/);
       transform_later(store_eden_top);
-      Node *contention_check = new (C, 2) BoolNode( store_eden_top, BoolTest::ne );
+      Node *contention_check = new (C, 2) BoolNode(store_eden_top, BoolTest::ne);
       transform_later(contention_check);
       store_eden_top = new (C, 1) SCMemProjNode(store_eden_top);
       transform_later(store_eden_top);
 
       // If not using TLABs, check to see if there was contention.
-      IfNode *contention_iff = new (C, 2) IfNode ( needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN );
+      IfNode *contention_iff = new (C, 2) IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN);
       transform_later(contention_iff);
-      Node *contention_true = new (C, 1) IfTrueNode( contention_iff );
+      Node *contention_true = new (C, 1) IfTrueNode(contention_iff);
       transform_later(contention_true);
       // If contention, loopback and try again.
-      contended_region->init_req( contended_loopback_path, contention_true );
-      contended_phi_rawmem->init_req( contended_loopback_path, store_eden_top );
+      contended_region->init_req(contended_loopback_path, contention_true);
+      contended_phi_rawmem->init_req(contended_loopback_path, store_eden_top);
 
       // Fast-path succeeded with no contention!
-      Node *contention_false = new (C, 1) IfFalseNode( contention_iff );
+      Node *contention_false = new (C, 1) IfFalseNode(contention_iff);
       transform_later(contention_false);
       fast_oop_ctrl = contention_false;
+
+      // Bump total allocated bytes for this thread
+      Node* thread = new (C, 1) ThreadLocalNode();
+      transform_later(thread);
+      Node* alloc_bytes_adr = basic_plus_adr(top()/*not oop*/, thread,
+                                             in_bytes(JavaThread::allocated_bytes_offset()));
+      Node* alloc_bytes = make_load(fast_oop_ctrl, store_eden_top, alloc_bytes_adr,
+                                    0, TypeLong::LONG, T_LONG);
+#ifdef _LP64
+      Node* alloc_size = size_in_bytes;
+#else
+      Node* alloc_size = new (C, 2) ConvI2LNode(size_in_bytes);
+      transform_later(alloc_size);
+#endif
+      Node* new_alloc_bytes = new (C, 3) AddLNode(alloc_bytes, alloc_size);
+      transform_later(new_alloc_bytes);
+      fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr,
+                                   0, new_alloc_bytes, T_LONG);
     }
 
-    // Rename successful fast-path variables to make meaning more obvious
-    Node* fast_oop        = old_eden_top;
-    Node* fast_oop_rawmem = store_eden_top;
     fast_oop_rawmem = initialize_object(alloc,
                                         fast_oop_ctrl, fast_oop_rawmem, fast_oop,
                                         klass_node, length, size_in_bytes);
@@ -1282,11 +1305,11 @@
 
       call->init_req(TypeFunc::Parms+0, thread);
       call->init_req(TypeFunc::Parms+1, fast_oop);
-      call->init_req( TypeFunc::Control, fast_oop_ctrl );
-      call->init_req( TypeFunc::I_O    , top() )        ;   // does no i/o
-      call->init_req( TypeFunc::Memory , fast_oop_rawmem );
-      call->init_req( TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr) );
-      call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) );
+      call->init_req(TypeFunc::Control, fast_oop_ctrl);
+      call->init_req(TypeFunc::I_O    , top()); // does no i/o
+      call->init_req(TypeFunc::Memory , fast_oop_rawmem);
+      call->init_req(TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr));
+      call->init_req(TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr));
       transform_later(call);
       fast_oop_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control);
       transform_later(fast_oop_ctrl);
@@ -1295,10 +1318,10 @@
     }
 
     // Plug in the successful fast-path into the result merge point
-    result_region    ->init_req( fast_result_path, fast_oop_ctrl );
-    result_phi_rawoop->init_req( fast_result_path, fast_oop );
-    result_phi_i_o   ->init_req( fast_result_path, i_o );
-    result_phi_rawmem->init_req( fast_result_path, fast_oop_rawmem );
+    result_region    ->init_req(fast_result_path, fast_oop_ctrl);
+    result_phi_rawoop->init_req(fast_result_path, fast_oop);
+    result_phi_i_o   ->init_req(fast_result_path, i_o);
+    result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem);
   } else {
     slow_region = ctrl;
   }
--- a/hotspot/src/share/vm/opto/output.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/output.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1746,9 +1746,6 @@
   // Walk backwards over each basic block, computing the needed alignment
   // Walk over all the basic blocks
   scheduling.DoScheduling();
-
-  // Clear the BufferBlob used for scheduling.
-  clear_scratch_buffer_blob();
 }
 
 //------------------------------ComputeLocalLatenciesForward-------------------
--- a/hotspot/src/share/vm/opto/stringopts.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/opto/stringopts.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -59,7 +59,8 @@
   enum {
     StringMode,
     IntMode,
-    CharMode
+    CharMode,
+    StringNullCheckMode
   };
 
   StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end):
@@ -114,6 +115,9 @@
   void push_string(Node* value) {
     push(value, StringMode);
   }
+  void push_string_null_check(Node* value) {
+    push(value, StringNullCheckMode);
+  }
   void push_int(Node* value) {
     push(value, IntMode);
   }
@@ -416,7 +420,19 @@
             if (sig == ciSymbol::string_void_signature()) {
               // StringBuilder(String) so pick this up as the first argument
               assert(use->in(TypeFunc::Parms + 1) != NULL, "what?");
-              sc->push_string(use->in(TypeFunc::Parms + 1));
+              const Type* type = _gvn->type(use->in(TypeFunc::Parms + 1));
+              if (type == TypePtr::NULL_PTR) {
+                // StringBuilder(null) throws exception.
+#ifndef PRODUCT
+                if (PrintOptimizeStringConcat) {
+                  tty->print("giving up because StringBuilder(null) throws exception");
+                  alloc->jvms()->dump_spec(tty); tty->cr();
+                }
+#endif
+                return NULL;
+              }
+              // StringBuilder(str) argument needs null check.
+              sc->push_string_null_check(use->in(TypeFunc::Parms + 1));
             }
             // The int variant takes an initial size for the backing
             // array so just treat it like the void version.
@@ -436,7 +452,7 @@
 #ifndef PRODUCT
         if (PrintOptimizeStringConcat) {
           tty->print("giving up because couldn't find constructor ");
-          alloc->jvms()->dump_spec(tty);
+          alloc->jvms()->dump_spec(tty); tty->cr();
         }
 #endif
         break;
@@ -1269,6 +1285,25 @@
         string_sizes->init_req(argi, string_size);
         break;
       }
+      case StringConcat::StringNullCheckMode: {
+        const Type* type = kit.gvn().type(arg);
+        assert(type != TypePtr::NULL_PTR, "missing check");
+        if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
+          // Null check with uncommont trap since
+          // StringBuilder(null) throws exception.
+          // Use special uncommon trap instead of
+          // calling normal do_null_check().
+          Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
+          IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
+          overflow->add_req(__ IfFalse(iff));
+          Node* notnull = __ IfTrue(iff);
+          kit.set_control(notnull); // set control for the cast_not_null
+          arg = kit.cast_not_null(arg, false);
+          sc->set_argument(argi, arg);
+        }
+        assert(kit.gvn().type(arg)->higher_equal(TypeInstPtr::NOTNULL), "sanity");
+        // Fallthrough to add string length.
+      }
       case StringConcat::StringMode: {
         const Type* type = kit.gvn().type(arg);
         if (type == TypePtr::NULL_PTR) {
@@ -1328,6 +1363,7 @@
     // Hook
     PreserveJVMState pjvms(&kit);
     kit.set_control(overflow);
+    C->record_for_igvn(overflow);
     kit.uncommon_trap(Deoptimization::Reason_intrinsic,
                       Deoptimization::Action_make_not_entrant);
   }
@@ -1363,6 +1399,7 @@
         start = end;
         break;
       }
+      case StringConcat::StringNullCheckMode:
       case StringConcat::StringMode: {
         start = copy_string(kit, arg, char_array, start);
         break;
--- a/hotspot/src/share/vm/prims/jvmti.xml	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/jvmti.xml	Wed Jan 19 19:00:30 2011 -0800
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
 <!--
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
  This code is free software; you can redistribute it and/or modify it
@@ -10697,7 +10697,7 @@
 	    <internallink id="mUTF">modified UTF-8</internallink> string.
 	  </description>
 	</param>
-        <param id="value">
+        <param id="value_ptr">
 	  <inbuf>
 	    <char/>
 	    <nullok>
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1802,7 +1802,7 @@
 // depth - pre-checked as non-negative
 // value - pre-checked for NULL
 jvmtiError
-JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value){
+JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value_ptr){
   JavaThread* current_thread = JavaThread::current();
   // rm object is created to clean up the javaVFrame created in
   // doit_prologue(), but after doit() is finished with it.
@@ -1814,7 +1814,7 @@
   if (err != JVMTI_ERROR_NONE) {
     return err;
   } else {
-    *value = op.value().l;
+    *value_ptr = op.value().l;
     return JVMTI_ERROR_NONE;
   }
 } /* end GetLocalInstance */
@@ -3440,12 +3440,12 @@
 // property - pre-checked for NULL
 // value - NULL is a valid value, must be checked
 jvmtiError
-JvmtiEnv::SetSystemProperty(const char* property, const char* value) {
+JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
   jvmtiError err =JVMTI_ERROR_NOT_AVAILABLE;
 
   for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
     if (strcmp(property, p->key()) == 0) {
-      if (p->set_value((char *)value)) {
+      if (p->set_value((char *)value_ptr)) {
         err =  JVMTI_ERROR_NONE;
       }
     }
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -111,7 +111,7 @@
 //------------------------------------------------------------------------------
 // MethodHandles::generate_adapters
 //
-void MethodHandles::generate_adapters() {
+void MethodHandles::generate_adapters(TRAPS) {
   if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL)  return;
 
   assert(_adapter_code == NULL, "generate only once");
@@ -123,20 +123,20 @@
     vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
   CodeBuffer code(_adapter_code);
   MethodHandlesAdapterGenerator g(&code);
-  g.generate();
+  g.generate(CHECK);
 }
 
 
 //------------------------------------------------------------------------------
 // MethodHandlesAdapterGenerator::generate
 //
-void MethodHandlesAdapterGenerator::generate() {
+void MethodHandlesAdapterGenerator::generate(TRAPS) {
   // 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);
+    MethodHandles::generate_method_handle_stub(_masm, ek, CHECK);
   }
 }
 
@@ -2645,5 +2645,10 @@
       MethodHandles::set_enabled(true);
     }
   }
+
+  // Generate method handles adapters if enabled.
+  if (MethodHandles::enabled()) {
+    MethodHandles::generate_adapters(CHECK);
+  }
 }
 JVM_END
--- a/hotspot/src/share/vm/prims/methodHandles.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -294,11 +294,11 @@
   enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
 
   // Generate MethodHandles adapters.
-  static void generate_adapters();
+  static void generate_adapters(TRAPS);
 
   // Called from InterpreterGenerator and MethodHandlesAdapterGenerator.
   static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
-  static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
+  static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek, TRAPS);
 
   // argument list parsing
   static int argument_slot(oop method_type, int arg);
@@ -530,7 +530,7 @@
 public:
   MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code) {}
 
-  void generate();
+  void generate(TRAPS);
 };
 
 #endif // SHARE_VM_PRIMS_METHODHANDLES_HPP
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -2297,14 +2297,15 @@
     } else if (match_option(option, "-Xoss", &tail)) {
           // HotSpot does not have separate native and Java stacks, ignore silently for compatibility
     // -Xmaxjitcodesize
-    } else if (match_option(option, "-Xmaxjitcodesize", &tail)) {
+    } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
+               match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
       julong long_ReservedCodeCacheSize = 0;
       ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize,
                                             (size_t)InitialCodeCacheSize);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum code cache size: %s\n",
-                    option->optionString);
+                    "Invalid maximum code cache size: %s. Should be greater than InitialCodeCacheSize=%dK\n",
+                    option->optionString, InitialCodeCacheSize/K);
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
--- a/hotspot/src/share/vm/runtime/init.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/init.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -125,9 +125,6 @@
   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/hotspot/src/share/vm/runtime/java.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/java.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -515,8 +515,8 @@
 }
 
 void vm_exit(int code) {
-  Thread* thread = ThreadLocalStorage::thread_index() == -1 ? NULL
-    : ThreadLocalStorage::get_thread_slow();
+  Thread* thread = ThreadLocalStorage::is_initialized() ?
+    ThreadLocalStorage::get_thread_slow() : NULL;
   if (thread == NULL) {
     // we have serious problems -- just exit
     vm_direct_exit(code);
@@ -553,8 +553,9 @@
   // Calling 'exit_globals()' will disable thread-local-storage and cause all
   // kinds of assertions to trigger in debug mode.
   if (is_init_completed()) {
-    Thread* thread = Thread::current();
-    if (thread->is_Java_thread()) {
+    Thread* thread = ThreadLocalStorage::is_initialized() ?
+                     ThreadLocalStorage::get_thread_slow() : NULL;
+    if (thread != NULL && thread->is_Java_thread()) {
       // We are leaving the VM, set state to native (in case any OS exit
       // handlers call back to the VM)
       JavaThread* jt = (JavaThread*)thread;
--- a/hotspot/src/share/vm/runtime/thread.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -177,20 +177,19 @@
 
 
 Thread::Thread() {
-  // stack
-  _stack_base   = NULL;
-  _stack_size   = 0;
-  _self_raw_id  = 0;
-  _lgrp_id      = -1;
-  _osthread     = NULL;
+  // stack and get_thread
+  set_stack_base(NULL);
+  set_stack_size(0);
+  set_self_raw_id(0);
+  set_lgrp_id(-1);
 
   // allocated data structures
+  set_osthread(NULL);
   set_resource_area(new ResourceArea());
   set_handle_area(new HandleArea(NULL));
   set_active_handles(NULL);
   set_free_handle_block(NULL);
   set_last_handle_mark(NULL);
-  set_osthread(NULL);
 
   // This initial value ==> never claimed.
   _oops_do_parity = 0;
@@ -205,6 +204,7 @@
   NOT_PRODUCT(_skip_gcalot = false;)
   CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
   _jvmti_env_iteration_count = 0;
+  set_allocated_bytes(0);
   _vm_operation_started_count = 0;
   _vm_operation_completed_count = 0;
   _current_pending_monitor = NULL;
@@ -3231,7 +3231,7 @@
       warning("java.lang.ArithmeticException has not been initialized");
       warning("java.lang.StackOverflowError has not been initialized");
     }
-  }
+    }
 
   // See        : bugid 4211085.
   // Background : the static initializer of java.lang.Compiler tries to read
--- a/hotspot/src/share/vm/runtime/thread.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
 class JvmtiGetLoadedClassesClosure;
 class ThreadStatistics;
 class ConcurrentLocksDump;
-class ParkEvent ;
+class ParkEvent;
 class Parker;
 
 class ciEnv;
@@ -170,7 +170,7 @@
   //
 
   // suspend/resume lock: used for self-suspend
-  Monitor*    _SR_lock;
+  Monitor* _SR_lock;
 
  protected:
   enum SuspendFlags {
@@ -194,7 +194,7 @@
  public:
   void enter_signal_handler() { _num_nested_signal++; }
   void leave_signal_handler() { _num_nested_signal--; }
-  bool is_inside_signal_handler() const  { return _num_nested_signal > 0; }
+  bool is_inside_signal_handler() const { return _num_nested_signal > 0; }
 
  private:
   // Debug tracing
@@ -215,7 +215,7 @@
 
   public:
    void set_last_handle_mark(HandleMark* mark)   { _last_handle_mark = mark; }
-    HandleMark* last_handle_mark() const          { return _last_handle_mark; }
+   HandleMark* last_handle_mark() const          { return _last_handle_mark; }
   private:
 
   // debug support for checking if code does allow safepoints or not
@@ -227,11 +227,11 @@
   //
   // The two classes No_Safepoint_Verifier and No_Allocation_Verifier are used to set these counters.
   //
-  NOT_PRODUCT(int _allow_safepoint_count;)       // If 0, thread allow a safepoint to happen
-  debug_only (int _allow_allocation_count;)      // If 0, the thread is allowed to allocate oops.
+  NOT_PRODUCT(int _allow_safepoint_count;)      // If 0, thread allow a safepoint to happen
+  debug_only (int _allow_allocation_count;)     // If 0, the thread is allowed to allocate oops.
 
   // Used by SkipGCALot class.
-  NOT_PRODUCT(bool _skip_gcalot;)                // Should we elide gc-a-lot?
+  NOT_PRODUCT(bool _skip_gcalot;)               // Should we elide gc-a-lot?
 
   // Record when GC is locked out via the GC_locker mechanism
   CHECK_UNHANDLED_OOPS_ONLY(int _gc_locked_out_count;)
@@ -242,24 +242,26 @@
   friend class ThreadLocalStorage;
   friend class GC_locker;
 
-  ThreadLocalAllocBuffer _tlab;                  // Thread-local eden
+  ThreadLocalAllocBuffer _tlab;                 // Thread-local eden
+  jlong _allocated_bytes;                       // Cumulative number of bytes allocated on
+                                                // the Java heap
 
-  int   _vm_operation_started_count;             // VM_Operation support
-  int   _vm_operation_completed_count;           // VM_Operation support
+  int   _vm_operation_started_count;            // VM_Operation support
+  int   _vm_operation_completed_count;          // VM_Operation support
 
-  ObjectMonitor* _current_pending_monitor;       // ObjectMonitor this thread
-                                                 // is waiting to lock
-  bool _current_pending_monitor_is_from_java;    // locking is from Java code
+  ObjectMonitor* _current_pending_monitor;      // ObjectMonitor this thread
+                                                // is waiting to lock
+  bool _current_pending_monitor_is_from_java;   // locking is from Java code
 
   // ObjectMonitor on which this thread called Object.wait()
   ObjectMonitor* _current_waiting_monitor;
 
   // Private thread-local objectmonitor list - a simple cache organized as a SLL.
  public:
-  ObjectMonitor * omFreeList ;
-  int omFreeCount ;                             // length of omFreeList
-  int omFreeProvision ;                         // reload chunk size
-  ObjectMonitor * omInUseList;                  // SLL to track monitors in circulation
+  ObjectMonitor* omFreeList;
+  int omFreeCount;                              // length of omFreeList
+  int omFreeProvision;                          // reload chunk size
+  ObjectMonitor* omInUseList;                   // SLL to track monitors in circulation
   int omInUseCount;                             // length of omInUseList
 
  public:
@@ -280,7 +282,6 @@
   // Testers
   virtual bool is_VM_thread()       const            { return false; }
   virtual bool is_Java_thread()     const            { return false; }
-  // Remove this ifdef when C1 is ported to the compiler interface.
   virtual bool is_Compiler_thread() const            { return false; }
   virtual bool is_hidden_from_external_view() const  { return false; }
   virtual bool is_jvmti_agent_thread() const         { return false; }
@@ -344,15 +345,15 @@
   // Support for Unhandled Oop detection
 #ifdef CHECK_UNHANDLED_OOPS
  private:
-  UnhandledOops *_unhandled_oops;
+  UnhandledOops* _unhandled_oops;
  public:
-  UnhandledOops* unhandled_oops()               { return _unhandled_oops; }
+  UnhandledOops* unhandled_oops() { return _unhandled_oops; }
   // Mark oop safe for gc.  It may be stack allocated but won't move.
-  void allow_unhandled_oop(oop *op)              {
+  void allow_unhandled_oop(oop *op) {
     if (CheckUnhandledOops) unhandled_oops()->allow_unhandled_oop(op);
   }
   // Clear oops at safepoint so crashes point to unhandled oop violator
-  void clear_unhandled_oops()                   {
+  void clear_unhandled_oops() {
     if (CheckUnhandledOops) unhandled_oops()->clear_unhandled_oops();
   }
   bool is_gc_locked_out() { return _gc_locked_out_count > 0; }
@@ -392,6 +393,22 @@
     }
   }
 
+  jlong allocated_bytes()               { return _allocated_bytes; }
+  void set_allocated_bytes(jlong value) { _allocated_bytes = value; }
+  void incr_allocated_bytes(jlong size) { _allocated_bytes += size; }
+  jlong cooked_allocated_bytes() {
+    jlong allocated_bytes = OrderAccess::load_acquire(&_allocated_bytes);
+    if (UseTLAB) {
+      size_t used_bytes = tlab().used_bytes();
+      if ((ssize_t)used_bytes > 0) {
+        // More-or-less valid tlab.  The load_acquire above should ensure
+        // that the result of the add is <= the instantaneous value
+        return allocated_bytes + used_bytes;
+      }
+    }
+    return allocated_bytes;
+  }
+
   // VM operation support
   int vm_operation_ticket()                      { return ++_vm_operation_started_count; }
   int vm_operation_completed_count()             { return _vm_operation_completed_count; }
@@ -489,8 +506,11 @@
     return (_stack_base >= adr && adr >= (_stack_base - _stack_size));
   }
 
-  int     lgrp_id() const                 { return _lgrp_id; }
-  void    set_lgrp_id(int value)          { _lgrp_id = value; }
+  uintptr_t self_raw_id()                    { return _self_raw_id; }
+  void      set_self_raw_id(uintptr_t value) { _self_raw_id = value; }
+
+  int     lgrp_id() const        { return _lgrp_id; }
+  void    set_lgrp_id(int value) { _lgrp_id = value; }
 
   // Printing
   void print_on(outputStream* st) const;
@@ -502,7 +522,7 @@
 #ifdef ASSERT
  private:
   // Deadlock detection support for Mutex locks. List of locks own by thread.
-  Monitor *_owned_locks;
+  Monitor* _owned_locks;
   // Mutex::set_owner_implementation is the only place where _owned_locks is modified,
   // thus the friendship
   friend class Mutex;
@@ -511,7 +531,7 @@
  public:
   void print_owned_locks_on(outputStream* st) const;
   void print_owned_locks() const                 { print_owned_locks_on(tty);    }
-  Monitor * owned_locks() const                  { return _owned_locks;          }
+  Monitor* owned_locks() const                   { return _owned_locks;          }
   bool owns_locks() const                        { return owned_locks() != NULL; }
   bool owns_locks_but_compiled_lock() const;
 
@@ -538,7 +558,7 @@
   static ByteSize stack_size_offset()            { return byte_offset_of(Thread, _stack_size ); }
 
 #define TLAB_FIELD_OFFSET(name) \
-  static ByteSize tlab_##name##_offset()            { return byte_offset_of(Thread, _tlab) + ThreadLocalAllocBuffer::name##_offset(); }
+  static ByteSize tlab_##name##_offset()         { return byte_offset_of(Thread, _tlab) + ThreadLocalAllocBuffer::name##_offset(); }
 
   TLAB_FIELD_OFFSET(start)
   TLAB_FIELD_OFFSET(end)
@@ -552,6 +572,8 @@
 
 #undef TLAB_FIELD_OFFSET
 
+  static ByteSize allocated_bytes_offset()       { return byte_offset_of(Thread, _allocated_bytes ); }
+
  public:
   volatile intptr_t _Stalled ;
   volatile int _TypeTag ;
--- a/hotspot/src/share/vm/services/jmm.h	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/jmm.h	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,8 @@
   unsigned int isBootClassPathSupported : 1;
   unsigned int isObjectMonitorUsageSupported : 1;
   unsigned int isSynchronizerUsageSupported : 1;
-  unsigned int : 24;
+  unsigned int isThreadAllocatedMemorySupported : 1;
+  unsigned int : 23;
 } jmmOptionalSupport;
 
 typedef enum {
@@ -105,7 +106,8 @@
   JMM_VERBOSE_GC                     = 21,
   JMM_VERBOSE_CLASS                  = 22,
   JMM_THREAD_CONTENTION_MONITORING   = 23,
-  JMM_THREAD_CPU_TIME                = 24
+  JMM_THREAD_CPU_TIME                = 24,
+  JMM_THREAD_ALLOCATED_MEMORY        = 25
 } jmmBoolAttribute;
 
 
@@ -213,7 +215,10 @@
   jobject      (JNICALL *GetMemoryPoolUsage)     (JNIEnv* env, jobject pool);
   jobject      (JNICALL *GetPeakMemoryPoolUsage) (JNIEnv* env, jobject pool);
 
-  void*        reserved4;
+  void         (JNICALL *GetThreadAllocatedMemory)
+                                                 (JNIEnv *env,
+                                                  jlongArray ids,
+                                                  jlongArray sizeArray);
 
   jobject      (JNICALL *GetMemoryUsage)         (JNIEnv* env, jboolean heap);
 
@@ -228,6 +233,8 @@
                                                   jlong* result);
 
   jobjectArray (JNICALL *FindCircularBlockedThreads) (JNIEnv *env);
+
+  // Not used in JDK 6 or JDK 7
   jlong        (JNICALL *GetThreadCpuTime)       (JNIEnv *env, jlong thread_id);
 
   jobjectArray (JNICALL *GetVMGlobalNames)       (JNIEnv *env);
@@ -262,14 +269,22 @@
   void         (JNICALL *GetLastGCStat)          (JNIEnv *env,
                                                   jobject mgr,
                                                   jmmGCStat *gc_stat);
-  jlong        (JNICALL *GetThreadCpuTimeWithKind) (JNIEnv *env,
-                                                    jlong thread_id,
-                                                    jboolean user_sys_cpu_time);
-  void*        reserved5;
+
+  jlong        (JNICALL *GetThreadCpuTimeWithKind)
+                                                 (JNIEnv *env,
+                                                  jlong thread_id,
+                                                  jboolean user_sys_cpu_time);
+  void         (JNICALL *GetThreadCpuTimesWithKind)
+                                                 (JNIEnv *env,
+                                                  jlongArray ids,
+                                                  jlongArray timeArray,
+                                                  jboolean user_sys_cpu_time);
+
   jint         (JNICALL *DumpHeap0)              (JNIEnv *env,
                                                   jstring outputfile,
                                                   jboolean live);
-  jobjectArray (JNICALL *FindDeadlocks)             (JNIEnv *env, jboolean object_monitors_only);
+  jobjectArray (JNICALL *FindDeadlocks)          (JNIEnv *env,
+                                                  jboolean object_monitors_only);
   void         (JNICALL *SetVMGlobal)            (JNIEnv *env,
                                                   jstring flag_name,
                                                   jvalue  new_value);
--- a/hotspot/src/share/vm/services/management.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/management.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -101,12 +101,14 @@
     _optional_support.isCurrentThreadCpuTimeSupported = 0;
     _optional_support.isOtherThreadCpuTimeSupported = 0;
   }
+
   _optional_support.isBootClassPathSupported = 1;
   _optional_support.isObjectMonitorUsageSupported = 1;
 #ifndef SERVICES_KERNEL
   // This depends on the heap inspector
   _optional_support.isSynchronizerUsageSupported = 1;
 #endif // SERVICES_KERNEL
+  _optional_support.isThreadAllocatedMemorySupported = 1;
 }
 
 void Management::initialize(TRAPS) {
@@ -386,11 +388,6 @@
 
 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
   int num_threads = ids_ah->length();
-  // should be non-empty array
-  if (num_threads == 0) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              "Empty array of thread IDs");
-  }
 
   // Validate input thread IDs
   int i = 0;
@@ -402,11 +399,9 @@
                 "Invalid thread ID entry");
     }
   }
-
 }
 
 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
-
   // check if the element of infoArray is of type ThreadInfo class
   klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
   klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass();
@@ -414,7 +409,6 @@
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "infoArray element type is not ThreadInfo class");
   }
-
 }
 
 
@@ -770,6 +764,45 @@
   return prev;
 JVM_END
 
+// Gets an array containing the amount of memory allocated on the Java
+// heap for a set of threads (in bytes).  Each element of the array is
+// the amount of memory allocated for the thread ID specified in the
+// corresponding entry in the given array of thread IDs; or -1 if the
+// thread does not exist or has terminated.
+JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
+                                             jlongArray sizeArray))
+  // Check if threads is null
+  if (ids == NULL || sizeArray == NULL) {
+    THROW(vmSymbols::java_lang_NullPointerException());
+  }
+
+  ResourceMark rm(THREAD);
+  typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+  typeArrayHandle ids_ah(THREAD, ta);
+
+  typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
+  typeArrayHandle sizeArray_h(THREAD, sa);
+
+  // validate the thread id array
+  validate_thread_id_array(ids_ah, CHECK);
+
+  // sizeArray must be of the same length as the given array of thread IDs
+  int num_threads = ids_ah->length();
+  if (num_threads != sizeArray_h->length()) {
+    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+              "The length of the given long array does not match the length of "
+              "the given array of thread IDs");
+  }
+
+  MutexLockerEx ml(Threads_lock);
+  for (int i = 0; i < num_threads; i++) {
+    JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
+    if (java_thread != NULL) {
+      sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
+    }
+  }
+JVM_END
+
 // Returns a java/lang/management/MemoryUsage object representing
 // the memory usage for the heap or non-heap memory.
 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
@@ -834,6 +867,8 @@
     return ThreadService::is_thread_monitoring_contention();
   case JMM_THREAD_CPU_TIME:
     return ThreadService::is_thread_cpu_time_enabled();
+  case JMM_THREAD_ALLOCATED_MEMORY:
+    return ThreadService::is_thread_allocated_memory_enabled();
   default:
     assert(0, "Unrecognized attribute");
     return false;
@@ -851,6 +886,8 @@
     return ThreadService::set_thread_monitoring_contention(flag != 0);
   case JMM_THREAD_CPU_TIME:
     return ThreadService::set_thread_cpu_time_enabled(flag != 0);
+  case JMM_THREAD_ALLOCATED_MEMORY:
+    return ThreadService::set_thread_allocated_memory_enabled(flag != 0);
   default:
     assert(0, "Unrecognized attribute");
     return false;
@@ -1096,6 +1133,7 @@
 //               maxDepth == 0  requests no stack trace.
 //   infoArray - array of ThreadInfo objects
 //
+// QQQ - Why does this method return a value instead of void?
 JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray))
   // Check if threads is null
   if (ids == NULL || infoArray == NULL) {
@@ -1159,7 +1197,6 @@
     }
   } else {
     // obtain thread dump with the specific list of threads with stack trace
-
     do_thread_dump(&dump_result,
                    ids_ah,
                    num_threads,
@@ -1252,8 +1289,6 @@
       continue;
     }
 
-
-
     ThreadStackTrace* stacktrace = ts->get_stack_trace();
     assert(stacktrace != NULL, "Must have a stack trace dumped");
 
@@ -1500,6 +1535,49 @@
   return -1;
 JVM_END
 
+// Gets an array containing the CPU times consumed by a set of threads
+// (in nanoseconds).  Each element of the array is the CPU time for the
+// thread ID specified in the corresponding entry in the given array
+// of thread IDs; or -1 if the thread does not exist or has terminated.
+// If user_sys_cpu_time = true, the sum of user level and system CPU time
+// for the given thread is returned; otherwise, only user level CPU time
+// is returned.
+JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
+                                              jlongArray timeArray,
+                                              jboolean user_sys_cpu_time))
+  // Check if threads is null
+  if (ids == NULL || timeArray == NULL) {
+    THROW(vmSymbols::java_lang_NullPointerException());
+  }
+
+  ResourceMark rm(THREAD);
+  typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+  typeArrayHandle ids_ah(THREAD, ta);
+
+  typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
+  typeArrayHandle timeArray_h(THREAD, tia);
+
+  // validate the thread id array
+  validate_thread_id_array(ids_ah, CHECK);
+
+  // timeArray must be of the same length as the given array of thread IDs
+  int num_threads = ids_ah->length();
+  if (num_threads != timeArray_h->length()) {
+    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+              "The length of the given long array does not match the length of "
+              "the given array of thread IDs");
+  }
+
+  MutexLockerEx ml(Threads_lock);
+  for (int i = 0; i < num_threads; i++) {
+    JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
+    if (java_thread != NULL) {
+      timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
+                                                      user_sys_cpu_time != 0));
+    }
+  }
+JVM_END
+
 // Returns a String array of all VM global flag names
 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
   // last flag entry is always NULL, so subtract 1
@@ -2020,7 +2098,7 @@
   jmm_GetMemoryManagers,
   jmm_GetMemoryPoolUsage,
   jmm_GetPeakMemoryPoolUsage,
-  NULL,
+  jmm_GetThreadAllocatedMemory,
   jmm_GetMemoryUsage,
   jmm_GetLongAttribute,
   jmm_GetBoolAttribute,
@@ -2038,7 +2116,7 @@
   jmm_GetGCExtAttributeInfo,
   jmm_GetLastGCStat,
   jmm_GetThreadCpuTimeWithKind,
-  NULL,
+  jmm_GetThreadCpuTimesWithKind,
   jmm_DumpHeap0,
   jmm_FindDeadlockedThreads,
   jmm_SetVMGlobal,
--- a/hotspot/src/share/vm/services/threadService.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/threadService.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@
 // Default is disabled.
 bool ThreadService::_thread_monitoring_contention_enabled = false;
 bool ThreadService::_thread_cpu_time_enabled = false;
+bool ThreadService::_thread_allocated_memory_enabled = false;
 
 PerfCounter*  ThreadService::_total_threads_count = NULL;
 PerfVariable* ThreadService::_live_threads_count = NULL;
@@ -84,6 +85,8 @@
   if (os::is_thread_cpu_time_supported()) {
     _thread_cpu_time_enabled = true;
   }
+
+  _thread_allocated_memory_enabled = true; // Always on, so enable it
 }
 
 void ThreadService::reset_peak_thread_count() {
@@ -181,6 +184,15 @@
   return prev;
 }
 
+bool ThreadService::set_thread_allocated_memory_enabled(bool flag) {
+  MutexLocker m(Management_lock);
+
+  bool prev = _thread_allocated_memory_enabled;
+  _thread_allocated_memory_enabled = flag;
+
+  return prev;
+}
+
 // GC support
 void ThreadService::oops_do(OopClosure* f) {
   for (ThreadDumpResult* dump = _threaddump_list; dump != NULL; dump = dump->next()) {
--- a/hotspot/src/share/vm/services/threadService.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/services/threadService.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,6 +65,7 @@
 
   static bool          _thread_monitoring_contention_enabled;
   static bool          _thread_cpu_time_enabled;
+  static bool          _thread_allocated_memory_enabled;
 
   // Need to keep the list of thread dump result that
   // keep references to methodOop since thread dump can be
@@ -83,6 +84,9 @@
   static bool set_thread_cpu_time_enabled(bool flag);
   static bool is_thread_cpu_time_enabled()    { return _thread_cpu_time_enabled; }
 
+  static bool set_thread_allocated_memory_enabled(bool flag);
+  static bool is_thread_allocated_memory_enabled() { return _thread_cpu_time_enabled; }
+
   static jlong get_total_thread_count()       { return _total_threads_count->get_value(); }
   static jlong get_peak_thread_count()        { return _peak_threads_count->get_value(); }
   static jlong get_live_thread_count()        { return _live_threads_count->get_value() - _exiting_threads_count; }
--- a/hotspot/src/share/vm/utilities/debug.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -226,7 +226,7 @@
 
 void report_vm_out_of_memory(const char* file, int line, size_t size,
                              const char* message) {
-  if (Debugging || error_is_suppressed(file, line)) return;
+  if (Debugging) return;
 
   // We try to gather additional information for the first out of memory
   // error only; gathering additional data might cause an allocation and a
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Wed Jan 19 19:00:30 2011 -0800
@@ -67,7 +67,7 @@
 // threads are blocked forever inside report_and_die().
 
 // Constructor for crashes
-VMError::VMError(Thread* thread, int sig, address pc, void* siginfo, void* context) {
+VMError::VMError(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context) {
     _thread = thread;
     _id = sig;
     _pc   = pc;
@@ -322,29 +322,51 @@
 
   STEP(10, "(printing fatal error message)")
 
-     st->print_cr("#");
-     st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
+    st->print_cr("#");
+    if (should_report_bug(_id)) {
+      st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
+    } else {
+      st->print_cr("# There is insufficient memory for the Java "
+                   "Runtime Environment to continue.");
+    }
 
   STEP(15, "(printing type of error)")
 
      switch(_id) {
        case oom_error:
-         st->print_cr("#");
-         st->print("# java.lang.OutOfMemoryError: ");
          if (_size) {
-           st->print("requested ");
-           sprintf(buf,SIZE_FORMAT,_size);
+           st->print("# Native memory allocation (malloc) failed to allocate ");
+           jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
            st->print(buf);
            st->print(" bytes");
            if (_message != NULL) {
              st->print(" for ");
              st->print(_message);
            }
-           st->print_cr(". Out of swap space?");
+           st->cr();
          } else {
            if (_message != NULL)
+             st->print("# ");
              st->print_cr(_message);
          }
+         // In error file give some solutions
+         if (_verbose) {
+           st->print_cr("# Possible reasons:");
+           st->print_cr("#   The system is out of physical RAM or swap space");
+           st->print_cr("#   In 32 bit mode, the process size limit was hit");
+           st->print_cr("# Possible solutions:");
+           st->print_cr("#   Reduce memory load on the system");
+           st->print_cr("#   Increase physical memory or swap space");
+           st->print_cr("#   Check if swap backing store is full");
+           st->print_cr("#   Use 64 bit Java on a 64 bit OS");
+           st->print_cr("#   Decrease Java heap size (-Xmx/-Xms)");
+           st->print_cr("#   Decrease number of Java threads");
+           st->print_cr("#   Decrease Java thread stack sizes (-Xss)");
+           st->print_cr("#   Set larger code cache with -XX:ReservedCodeCacheSize=");
+           st->print_cr("# This output file may be truncated or incomplete.");
+         } else {
+           return;  // that's enough for the screen
+         }
          break;
        case internal_error:
        default:
@@ -361,7 +383,11 @@
        st->print(" (0x%x)", _id);                // signal number
        st->print(" at pc=" PTR_FORMAT, _pc);
      } else {
-       st->print("Internal Error");
+       if (should_report_bug(_id)) {
+         st->print("Internal Error");
+       } else {
+         st->print("Out of Memory Error");
+       }
        if (_filename != NULL && _lineno > 0) {
 #ifdef PRODUCT
          // In product mode chop off pathname?
@@ -393,12 +419,14 @@
 
   STEP(40, "(printing error message)")
 
-     // error message
-     if (_detail_msg) {
-       st->print_cr("#  %s: %s", _message ? _message : "Error", _detail_msg);
-     } else if (_message) {
-       st->print_cr("#  Error: %s", _message);
-     }
+     if (should_report_bug(_id)) {  // already printed the message.
+       // error message
+       if (_detail_msg) {
+         st->print_cr("#  %s: %s", _message ? _message : "Error", _detail_msg);
+       } else if (_message) {
+         st->print_cr("#  Error: %s", _message);
+       }
+    }
 
   STEP(50, "(printing Java version string)")
 
@@ -428,7 +456,9 @@
 
   STEP(65, "(printing bug submit message)")
 
-     if (_verbose) print_bug_submit_message(st, _thread);
+     if (should_report_bug(_id) && _verbose) {
+       print_bug_submit_message(st, _thread);
+     }
 
   STEP(70, "(printing thread)" )
 
@@ -906,7 +936,7 @@
     OnError = NULL;
   }
 
-  static bool skip_bug_url = false;
+  static bool skip_bug_url = !should_report_bug(first_error->_id);
   if (!skip_bug_url) {
     skip_bug_url = true;
 
@@ -919,7 +949,8 @@
     static bool skip_os_abort = false;
     if (!skip_os_abort) {
       skip_os_abort = true;
-      os::abort();
+      bool dump_core = should_report_bug(first_error->_id);
+      os::abort(dump_core);
     }
 
     // if os::abort() doesn't abort, try os::die();
--- a/hotspot/src/share/vm/utilities/vmError.hpp	Mon Jan 17 13:29:12 2011 +0530
+++ b/hotspot/src/share/vm/utilities/vmError.hpp	Wed Jan 19 19:00:30 2011 -0800
@@ -87,10 +87,12 @@
   // accessor
   const char* message() const    { return _message; }
   const char* detail_msg() const { return _detail_msg; }
+  bool should_report_bug(unsigned int id) { return id != oom_error; }
 
 public:
   // Constructor for crashes
-  VMError(Thread* thread, int sig, address pc, void* siginfo, void* context);
+  VMError(Thread* thread, unsigned int sig, address pc, void* siginfo,
+          void* context);
   // Constructor for VM internal errors
   VMError(Thread* thread, const char* filename, int lineno,
           const char* message, const char * detail_msg);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6579789/Test6579789.java	Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6579789
+ * @summary Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
+ * @run main/othervm -Xcomp -XX:UseSSE=0 -XX:CompileOnly=Test6579789.bug Test6579789
+ */
+
+public class Test6579789 {
+    public static void main(String[] args) {
+        bug(4);
+    }
+    public static void bug(int n) {
+        float f = 1;
+        int i = 1;
+        try {
+            int x = 1 / n; // instruction that can trap
+            f = 2;
+            i = 2;
+            int y = 2 / n; // instruction that can trap
+        } catch (Exception ex) {
+            f++;
+            i++;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7009231/Test7009231.java	Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7009231
+ * @summary C1: Incorrect CAS code for longs on SPARC 32bit
+ *
+ * @run main/othervm -Xbatch Test7009231
+ *
+ */
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicLong;
+
+
+public class Test7009231 {
+    public static void main(String[] args) throws InterruptedException {
+        doTest(8);
+    }
+
+    private static void doTest(int nThreads) throws InterruptedException {
+        Thread[]         aThreads = new Thread[nThreads];
+        final AtomicLong atl      = new AtomicLong();
+
+        for (int i = 0; i < nThreads; i++) {
+          aThreads[i] = new RunnerThread(atl, 1L << (8 * i));
+        }
+
+        for (int i = 0; i < nThreads; i++) {
+          aThreads[i].start();
+        }
+
+        for (int i = 0; i < nThreads; i++) {
+          aThreads[i].join();
+        }
+    }
+
+    public static class RunnerThread extends Thread {
+        public RunnerThread(AtomicLong atomic, long lMask) {
+            m_lMask  = lMask;
+            m_atomic = atomic;
+        }
+
+        public void run() {
+            AtomicLong atomic = m_atomic;
+            long       lMask  = m_lMask;
+            for (int i = 0; i < 100000; i++) {
+                setBit(atomic, lMask);
+                clearBit(atomic, lMask);
+            }
+        }
+
+        protected void setBit(AtomicLong atomic, long lMask) {
+            long lWord;
+            do {
+                lWord = atomic.get();
+            } while (!atomic.compareAndSet(lWord, lWord | lMask));
+
+            if ((atomic.get() & lMask) == 0L) {
+                throw new InternalError();
+            }
+        }
+
+        protected void clearBit(AtomicLong atomic, long lMask) {
+            long lWord;
+            do {
+                lWord = atomic.get();
+            } while (!atomic.compareAndSet(lWord, lWord & ~lMask));
+
+            if ((atomic.get() & lMask) != 0L) {
+                throw new InternalError();
+            }
+        }
+
+        private long m_lMask;
+        private AtomicLong m_atomic;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7009359/Test7009359.java	Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7009359
+ * @summary HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
+ *
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+OptimizeStringConcat -XX:CompileCommand=exclude,Test7009359,main Test7009359
+ *
+ */
+
+public class Test7009359 {
+    public static void main (String[] args) {
+        for(int i = 0; i < 1000000; i++) {
+            if(!stringmakerBUG(null).equals("NPE")) {
+                System.out.println("StringBuffer(null) does not throw NPE");
+                System.exit(97);
+            }
+        }
+    }
+
+    public static String stringmakerBUG(String str) {
+       try {
+           return new StringBuffer(str).toString();
+       } catch (NullPointerException e) {
+           return "NPE";
+       }
+    }
+}
+
--- a/jaxp/.hgtags	Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxp/.hgtags	Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
 63dae40fa19fd3bf4689ea2f3c1d9d690e1abcee jdk7-b121
 03ff13d19c8fa983cbab6542930a7f352e9b5b33 jdk7-b122
 e2aedea6495d61557326928de20dbb2d78fdd9aa jdk7-b123
+57ed1f3bec72924cdad102f9bf90f7449ea7bb83 jdk7-b124
+6c9bdee0cc3a8912acc5189cc092b8cba6851f9d jdk7-b125
--- a/jaxp/jaxp.properties	Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxp/jaxp.properties	Wed Jan 19 19:00:30 2011 -0800
@@ -25,13 +25,13 @@
 
 drops.master.copy.base=${drops.dir}
 
-jaxp_src.bundle.name=jaxp-1_4_4.zip
-jaxp_src.bundle.md5.checksum=2c40a758392c4abf2d59f355240df46a
+jaxp_src.bundle.name=jaxp-1_4_5-dev.zip
+jaxp_src.bundle.md5.checksum=84e2c26853262c9144133c6ff7ef5dc9
 jaxp_src.master.bundle.dir=${drops.master.copy.base}
-jaxp_src.master.bundle.url.base=https://java.net/downloads/jaxp/jdk7
+jaxp_src.master.bundle.url.base=http://download.java.net/jaxp/1.4.5/dev
 
-#jaxp_tests.bundle.name=jaxp-unittests-1_4_4.zip
-#jaxp_tests.bundle.md5.checksum=51845e38b02920cf5374d0331ab3a4ee
-#jaxp_tests.master.bundle.dir=${drops.master.copy.base}
-#jaxp_tests.master.bundle.url.base=https://java.net/downloads/jaxp/jdk7
+jaxp_tests.bundle.name=jaxp-1_4_5-dev-unittests.zip
+jaxp_tests.bundle.md5.checksum=0377e715fa21814cb8006768c5967dc5
+jaxp_tests.master.bundle.dir=${drops.master.copy.base}
+jaxp_tests.master.bundle.url.base=http://download.java.net/jaxp/1.4.5/dev
 
--- a/jaxws/.hgtags	Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxws/.hgtags	Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
 0fa950117faac7bdbc94e6c46b88f6f892031c17 jdk7-b121
 17b6c48a344968880925dcef1178fec282feb335 jdk7-b122
 5a8e43bcce56b7cd5576419067a929b74575ae71 jdk7-b123
+86f60e5b3975840968f3147ddce047a27a9fc83e jdk7-b124
+d72eea121c3bc2b649272a37b80d9417855b7146 jdk7-b125
--- a/jaxws/jaxws.properties	Mon Jan 17 13:29:12 2011 +0530
+++ b/jaxws/jaxws.properties	Wed Jan 19 19:00:30 2011 -0800
@@ -25,10 +25,10 @@
 
 drops.master.copy.base=${drops.dir}
 
-jaxws_src.bundle.name= jdk7-jaxws2_2-2010_08_19.zip
-jaxws_src.bundle.md5.checksum=8775ccefd3b4fa2dde5155ec4b7e4ceb
+jaxws_src.bundle.name=jdk7-jaxws2_2_2-2010_12_14.zip
+jaxws_src.bundle.md5.checksum=fee9ac72fabc96719eefc66ecaff4bc3
 jaxws_src.master.bundle.dir=${drops.master.copy.base}
-jaxws_src.master.bundle.url.base=https://java.net/downloads/jax-ws/JDK7
+jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk7
 
 jaf_src.bundle.name=jdk7-jaf-2010_08_19.zip
 jaf_src.bundle.md5.checksum=18d15dfd71117daadb332af003d08212
--- a/jdk/.hgtags	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/.hgtags	Wed Jan 19 19:00:30 2011 -0800
@@ -98,3 +98,5 @@
 a661d8587b5d8986aacae086f5df66af9e1a96b1 jdk7-b121
 ac311eb325bfc763698219252bf3cee9e091f3af jdk7-b122
 869190935eedee7750d955019ab2a1b80f0a13a8 jdk7-b123
+1c72adc9d5f331cb882cf5354ba0dcb118a60b23 jdk7-b124
+0a56bdd709d01c1663047e55201d19152ffd3d69 jdk7-b125
--- a/jdk/make/sun/Makefile	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/Makefile	Wed Jan 19 19:00:30 2011 -0800
@@ -42,7 +42,15 @@
   ifndef OPENJDK
     ifeq ($(PLATFORM), solaris)
       ifneq ($(ARCH), amd64)
-        DGA_SUBDIR = jdga
+        # Solaris 11 does not have support for new compilation of DGA code.
+        OS_VERSION = $(shell uname -r)
+        OS_MAJOR_VERSION := $(call MajorVersion,$(OS_VERSION))
+        OS_MINOR_VERSION := $(call MinorVersion,$(OS_VERSION))
+        ifeq ($(shell $(EXPR) $(OS_MAJOR_VERSION) == 5), 1)
+          ifeq ($(shell $(EXPR) $(OS_MINOR_VERSION) \<= 10), 1)
+            DGA_SUBDIR = jdga
+          endif
+        endif
       endif
     endif
   endif
--- a/jdk/make/sun/awt/Makefile	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/Makefile	Wed Jan 19 19:00:30 2011 -0800
@@ -175,6 +175,10 @@
 include $(BUILDDIR)/common/Mapfile-vers.gmk
 include $(BUILDDIR)/common/Library.gmk
 
+COMPILEFONTCONFIG_FLAGS =
+ifdef ALT_COMPILEFONTCONFIG_FLAGS
+  COMPILEFONTCONFIG_FLAGS += $(ALT_COMPILEFONTCONFIG_FLAGS)
+endif
 build: fontconfigs
 
 
@@ -406,7 +410,7 @@
 $(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \
     $(COMPILEFONTCONFIG_JARFILE)
 	$(prep-target)
-	$(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $< $@
+	$(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $(COMPILEFONTCONFIG_FLAGS) $< $@
 	$(install-module-file)
 	$(call chmod-file, 444)
 	@$(java-vm-cleanup)
--- a/jdk/make/sun/awt/make.depend	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/make.depend	Wed Jan 19 19:00:30 2011 -0800
@@ -224,7 +224,7 @@
 
 $(OBJDIR)/DrawLine.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawLine.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
-$(OBJDIR)/DrawParallelogram.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/LoopMacros.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
+$(OBJDIR)/DrawParallelogram.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
 $(OBJDIR)/DrawPath.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
@@ -232,7 +232,7 @@
 
 $(OBJDIR)/DrawRect.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawRect.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
-$(OBJDIR)/FillParallelogram.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
+$(OBJDIR)/FillParallelogram.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
 $(OBJDIR)/FillPath.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
@@ -284,7 +284,7 @@
 
 $(OBJDIR)/MaskBlit.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskBlit.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/Region.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/awt/utility/rect.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
-$(OBJDIR)/MaskFill.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
+$(OBJDIR)/MaskFill.obj::	$(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
 
 $(OBJDIR)/MouseInfo.obj::	$(CLASSHDRDIR)/java_awt_AWTEvent.h $(CLASSHDRDIR)/java_awt_Component.h $(CLASSHDRDIR)/java_awt_Dimension.h $(CLASSHDRDIR)/java_awt_Event.h $(CLASSHDRDIR)/java_awt_event_FocusEvent.h $(CLASSHDRDIR)/java_awt_event_KeyEvent.h $(CLASSHDRDIR)/java_awt_event_MouseEvent.h $(CLASSHDRDIR)/java_awt_event_WindowEvent.h $(CLASSHDRDIR)/java_awt_Font.h $(CLASSHDRDIR)/sun_awt_FontDescriptor.h $(CLASSHDRDIR)/sun_awt_PlatformFont.h $(CLASSHDRDIR)/sun_awt_windows_WComponentPeer.h $(CLASSHDRDIR)/sun_awt_windows_WFontMetrics.h $(CLASSHDRDIR)/sun_awt_windows_WObjectPeer.h $(CLASSHDRDIR)/sun_awt_windows_WToolkit.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/awt/image/cvutils/img_globals.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.h ../../../src/windows/native/sun/windows/alloc.h ../../../src/windows/native/sun/windows/awt.h ../../../src/windows/native/sun/windows/awtmsg.h ../../../src/windows/native/sun/windows/awt_Brush.h ../../../src/windows/native/sun/windows/awt_Component.h ../../../src/windows/native/sun/windows/awt_Debug.h ../../../src/windows/native/sun/windows/awt_Font.h ../../../src/windows/native/sun/windows/awt_GDIObject.h ../../../src/windows/native/sun/windows/awt_Object.h ../../../src/windows/native/sun/windows/awt_Palette.h ../../../src/windows/native/sun/windows/awt_Pen.h ../../../src/windows/native/sun/windows/awt_Toolkit.h ../../../src/windows/native/sun/windows/awt_Win32GraphicsDevice.h ../../../src/windows/native/sun/windows/colordata.h ../../../src/windows/native/sun/windows/Devices.h ../../../src/windows/native/sun/windows/GDIHashtable.h ../../../src/windows/native/sun/windows/Hashtable.h ../../../src/windows/native/sun/windows/ObjectList.h ../../../src/windows/native/sun/windows/stdhdrs.h
 
--- a/jdk/make/sun/awt/mapfile-vers	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/mapfile-vers	Wed Jan 19 19:00:30 2011 -0800
@@ -118,6 +118,8 @@
 		Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops;
 		Java_sun_java2d_loops_MaskBlit_MaskBlit;
 		Java_sun_java2d_loops_MaskFill_MaskFill;
+		Java_sun_java2d_loops_MaskFill_FillAAPgram;
+		Java_sun_java2d_loops_MaskFill_DrawAAPgram;
 		Java_sun_java2d_loops_TransformHelper_Transform;
 		Java_sun_java2d_pipe_Region_initIDs;
 		Java_sun_java2d_pipe_SpanClipRenderer_initIDs;
--- a/jdk/make/sun/awt/mapfile-vers-linux	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/sun/awt/mapfile-vers-linux	Wed Jan 19 19:00:30 2011 -0800
@@ -115,6 +115,8 @@
 		Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops;
 		Java_sun_java2d_loops_MaskBlit_MaskBlit;
 		Java_sun_java2d_loops_MaskFill_MaskFill;
+		Java_sun_java2d_loops_MaskFill_FillAAPgram;
+		Java_sun_java2d_loops_MaskFill_DrawAAPgram;
                 Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans;
 		Java_sun_java2d_pipe_SpanClipRenderer_initIDs;
 		sun_awt_image_GifImageDecoder_initIDs;
--- a/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/make/tools/src/build/tools/javazic/Zoneinfo.java	Wed Jan 19 19:00:30 2011 -0800
@@ -222,6 +222,7 @@
         boolean continued = false;
         Zone zone = null;
         String l;
+        lineNum = 0;
 
         try {
             while ((line = in.readLine()) != null) {
--- a/jdk/src/share/classes/java/awt/SplashScreen.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/SplashScreen.java	Wed Jan 19 19:00:30 2011 -0800
@@ -33,27 +33,17 @@
 import sun.awt.image.SunWritableRaster;
 
 /**
- * The splash screen can be created at application startup, before the
+ * The splash screen can be displayed at application startup, before the
  * Java Virtual Machine (JVM) starts. The splash screen is displayed as an
- * undecorated window containing an image. You can use GIF, JPEG, and PNG files
- * for the image. Animation (for GIF) and transparency (for GIF, PNG) are
- * supported. The window is positioned at the center of the screen (the
- * position on multi-monitor systems is not specified - it is platform and
- * implementation dependent).
- * The window is closed automatically as soon as the first window is displayed by
- * Swing/AWT (may be also closed manually using the Java API, see below).
+ * undecorated window containing an image. You can use GIF, JPEG, or PNG files
+ * for the image. Animation is supported for the GIF format, while transparency
+ * is supported both for GIF and PNG.  The window is positioned at the center
+ * of the screen. The position on multi-monitor systems is not specified. It is
+ * platform and implementation dependent.  The splash screen window is closed
+ * automatically as soon as the first window is displayed by Swing/AWT (may be
+ * also closed manually using the Java API, see below).
  * <P>
- * There are two ways to show the native splash screen:
- * <P>
- * <UL>
- * <LI>If your application is run from the command line or from a shortcut,
- * use the "-splash:" Java application  launcher option to show a splash screen.
- * <BR>
- * For example:
- * <PRE>
- * java -splash:filename.gif Test
- * </PRE>
- * <LI>If your application is packaged in a jar file, you can use the
+ * If your application is packaged in a jar file, you can use the
  * "SplashScreen-Image" option in a manifest file to show a splash screen.
  * Place the image in the jar archive and specify the path in the option.
  * The path should not have a leading slash.
@@ -64,18 +54,39 @@
  * Main-Class: Test
  * SplashScreen-Image: filename.gif
  * </PRE>
+ * <P>
+ * If the Java implementation provides the command-line interface and you run
+ * your application by using the command line or a shortcut, use the Java
+ * application launcher option to show a splash screen. The Oracle reference
+ * implementation allows you to specify the splash screen image location with
+ * the {@code -splash:} option.
+ * <BR>
+ * For example:
+ * <PRE>
+ * java -splash:filename.gif Test
+ * </PRE>
  * The command line interface has higher precedence over the manifest
  * setting.
- * </UL>
+ * <p>
+ * The splash screen will be displayed as faithfully as possible to present the
+ * whole splash screen image given the limitations of the target platform and
+ * display.
+ * <p>
+ * It is implied that the specified image is presented on the screen "as is",
+ * i.e. preserving the exact color values as specified in the image file. Under
+ * certain circumstances, though, the presented image may differ, e.g. when
+ * applying color dithering to present a 32 bits per pixel (bpp) image on a 16
+ * or 8 bpp screen. The native platform display configuration may also affect
+ * the colors of the displayed image (e.g.  color profiles, etc.)
  * <p>
  * The {@code SplashScreen} class provides the API for controlling the splash
  * screen. This class may be used to close the splash screen, change the splash
- * screen image, get the image position/size and paint in the splash screen. It
- * cannot be used to create the splash screen; you should use the command line or manifest
- * file option for that.
+ * screen image, get the splash screen native window position/size, and paint
+ * in the splash screen. It cannot be used to create the splash screen. You
+ * should use the options provided by the Java implementation for that.
  * <p>
  * This class cannot be instantiated. Only a single instance of this class
- * can exist, and it may be obtained using the {@link #getSplashScreen()}
+ * can exist, and it may be obtained by using the {@link #getSplashScreen()}
  * static method. In case the splash screen has not been created at
  * application startup via the command line or manifest file option,
  * the <code>getSplashScreen</code> method returns <code>null</code>.
@@ -91,7 +102,7 @@
 
     /**
      * Returns the {@code SplashScreen} object used for
-     * Java startup splash screen control.
+     * Java startup splash screen control on systems that support display.
      *
      * @throws UnsupportedOperationException if the splash screen feature is not
      *         supported by the current toolkit
@@ -219,6 +230,9 @@
      * <p>
      * You cannot control the size or position of the splash screen.
      * The splash screen size is adjusted automatically when the image changes.
+     * <p>
+     * The image may contain transparent areas, and thus the reported bounds may
+     * be larger than the visible splash screen image on the screen.
      *
      * @return a {@code Rectangle} containing the splash screen bounds
      * @throws IllegalStateException if the splash screen has already been closed
@@ -237,6 +251,9 @@
      * <p>
      * You cannot control the size or position of the splash screen.
      * The splash screen size is adjusted automatically when the image changes.
+     * <p>
+     * The image may contain transparent areas, and thus the reported size may
+     * be larger than the visible splash screen image on the screen.
      *
      * @return a {@link Dimension} object indicating the splash screen size
      * @throws IllegalStateException if the splash screen has already been closed
@@ -254,6 +271,10 @@
      * screen window. You should call {@code update()} on the
      * <code>SplashScreen</code> when you want the splash screen to be
      * updated immediately.
+     * <p>
+     * The pixel (0, 0) in the coordinate space of the graphics context
+     * corresponds to the origin of the splash screen native window bounds (see
+     * {@link #getBounds()}).
      *
      * @return graphics context for the splash screen overlay surface
      * @throws IllegalStateException if the splash screen has already been closed
@@ -334,6 +355,11 @@
      * Determines whether the splash screen is visible. The splash screen may
      * be hidden using {@link #close()}, it is also hidden automatically when
      * the first AWT/Swing window is made visible.
+     * <p>
+     * Note that the native platform may delay presenting the splash screen
+     * native window on the screen. The return value of {@code true} for this
+     * method only guarantees that the conditions to hide the splash screen
+     * window have not occurred yet.
      *
      * @return true if the splash screen is visible (has not been closed yet),
      *         false otherwise
--- a/jdk/src/share/classes/java/awt/font/NumericShaper.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java	Wed Jan 19 19:00:30 2011 -0800
@@ -58,20 +58,20 @@
  * It is also possible to perform numeric shaping explicitly using instances
  * of <code>NumericShaper</code>, as this code snippet demonstrates:<br>
  * <blockquote><pre>
- *   char[] text = ...;
- *   // shape all EUROPEAN digits (except zero) to ARABIC digits
- *   NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC);
- *   shaper.shape(text, start, count);
+ * char[] text = ...;
+ * // shape all EUROPEAN digits (except zero) to ARABIC digits
+ * NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC);
+ * shaper.shape(text, start, count);
  *
- *   // shape European digits to ARABIC digits if preceding text is Arabic, or
- *   // shape European digits to TAMIL digits if preceding text is Tamil, or
- *   // leave European digits alone if there is no preceding text, or
- *   // preceding text is neither Arabic nor Tamil
- *   NumericShaper shaper =
- *      NumericShaper.getContextualShaper(NumericShaper.ARABIC |
- *                                              NumericShaper.TAMIL,
- *                                              NumericShaper.EUROPEAN);
- *   shaper.shape(text, start, count);
+ * // shape European digits to ARABIC digits if preceding text is Arabic, or
+ * // shape European digits to TAMIL digits if preceding text is Tamil, or
+ * // leave European digits alone if there is no preceding text, or
+ * // preceding text is neither Arabic nor Tamil
+ * NumericShaper shaper =
+ *     NumericShaper.getContextualShaper(NumericShaper.ARABIC |
+ *                                         NumericShaper.TAMIL,
+ *                                       NumericShaper.EUROPEAN);
+ * shaper.shape(text, start, count);
  * </pre></blockquote>
  *
  * <p><b>Bit mask- and enum-based Unicode ranges</b></p>
@@ -99,6 +99,37 @@
  * values are specified, such as {@code NumericShaper.Range.BALINESE},
  * those ranges are ignored.
  *
+ * <p><b>Decimal Digits Precedence</b></p>
+ *
+ * <p>A Unicode range may have more than one set of decimal digits. If
+ * multiple decimal digits sets are specified for the same Unicode
+ * range, one of the sets will take precedence as follows.
+ *
+ * <table border=1 cellspacing=3 cellpadding=0 summary="NumericShaper constants precedence.">
+ *    <tr>
+ *       <th class="TableHeadingColor">Unicode Range</th>
+ *       <th class="TableHeadingColor"><code>NumericShaper</code> Constants</th>
+ *       <th class="TableHeadingColor">Precedence</th>
+ *    </tr>
+ *    <tr>
+ *       <td rowspan="2">Arabic</td>
+ *       <td>{@link NumericShaper#ARABIC NumericShaper.ARABIC}<br>
+ *           {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
+ *       <td>{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
+ *    </tr>
+ *    <tr>
+ *       <td>{@link NumericShaper.Range#ARABIC}<br>
+ *           {@link NumericShaper.Range#EASTERN_ARABIC}</td>
+ *       <td>{@link NumericShaper.Range#EASTERN_ARABIC}</td>
+ *    </tr>
+ *    <tr>
+ *       <td>Tai Tham</td>
+ *       <td>{@link NumericShaper.Range#TAI_THAM_HORA}<br>
+ *           {@link NumericShaper.Range#TAI_THAM_THAM}</td>
+ *       <td>{@link NumericShaper.Range#TAI_THAM_THAM}</td>
+ *    </tr>
+ * </table>
+ *
  * @since 1.4
  */
 
--- a/jdk/src/share/classes/java/awt/image/IndexColorModel.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/image/IndexColorModel.java	Wed Jan 19 19:00:30 2011 -0800
@@ -625,7 +625,7 @@
             }
             nBits[0] = nBits[1] = nBits[2] = 8;
         }
-        return nBits;
+        return nBits.clone();
     }
 
     /**
--- a/jdk/src/share/classes/java/awt/image/SampleModel.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/image/SampleModel.java	Wed Jan 19 19:00:30 2011 -0800
@@ -121,7 +121,7 @@
      */
     public SampleModel(int dataType, int w, int h, int numBands)
     {
-        float size = (float)w*h;
+        long size = (long)w * h;
         if (w <= 0 || h <= 0) {
             throw new IllegalArgumentException("Width ("+w+") and height ("+
                                                h+") must be > 0");
--- a/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java	Wed Jan 19 19:00:30 2011 -0800
@@ -92,7 +92,8 @@
      * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
      * Each sample is stored in a data array element in the position of
      * its corresponding bit mask.  Each bit mask must be contiguous and
-     * masks must not overlap.
+     * masks must not overlap. Bit masks exceeding data type capacity are
+     * truncated.
      * @param dataType  The data type for storing samples.
      * @param w         The width (in pixels) of the region of the
      *                  image data described.
@@ -120,7 +121,8 @@
      * and a scanline stride equal to scanlineStride data array elements.
      * Each sample is stored in a data array element in the position of
      * its corresponding bit mask.  Each bit mask must be contiguous and
-     * masks must not overlap.
+     * masks must not overlap. Bit masks exceeding data type capacity are
+     * truncated.
      * @param dataType  The data type for storing samples.
      * @param w         The width (in pixels) of the region of
      *                  image data described.
@@ -153,11 +155,13 @@
         this.bitOffsets = new int[numBands];
         this.bitSizes = new int[numBands];
 
+        int maxMask = (int)((1L << DataBuffer.getDataTypeSize(dataType)) - 1);
+
         this.maxBitSize = 0;
         for (int i=0; i<numBands; i++) {
             int bitOffset = 0, bitSize = 0, mask;
-            mask = bitMasks[i];
-
+            this.bitMasks[i] &= maxMask;
+            mask = this.bitMasks[i];
             if (mask != 0) {
                 while ((mask & 1) == 0) {
                     mask = mask >>> 1;
@@ -243,30 +247,12 @@
 
     /** Returns the number of bits per sample for all bands. */
     public int[] getSampleSize() {
-        int mask;
-        int sampleSize[] = new int [numBands];
-        for (int i=0; i<numBands; i++) {
-            sampleSize[i] = 0;
-            mask = bitMasks[i] >>> bitOffsets[i];
-            while ((mask & 1) != 0) {
-                sampleSize[i] ++;
-                mask = mask >>> 1;
-            }
-        }
-
-        return sampleSize;
+        return bitSizes.clone();
     }
 
     /** Returns the number of bits per sample for the specified band. */
     public int getSampleSize(int band) {
-        int sampleSize = 0;
-        int mask = bitMasks[band] >>> bitOffsets[band];
-        while ((mask & 1) != 0) {
-            sampleSize ++;
-            mask = mask >>> 1;
-        }
-
-        return sampleSize;
+        return bitSizes[band];
     }
 
     /** Returns the offset (in data array elements) of pixel (x,y).
--- a/jdk/src/share/classes/java/text/MessageFormat.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/text/MessageFormat.java	Wed Jan 19 19:00:30 2011 -0800
@@ -93,73 +93,65 @@
  *         currency
  *         percent
  *         <i>SubformatPattern</i>
- *
- * <i>String:</i>
- *         <i>StringPart<sub>opt</sub></i>
- *         <i>String</i> <i>StringPart</i>
- *
- * <i>StringPart:</i>
- *         ''
- *         ' <i>QuotedString</i> '
- *         <i>UnquotedString</i>
- *
- * <i>SubformatPattern:</i>
- *         <i>SubformatPatternPart<sub>opt</sub></i>
- *         <i>SubformatPattern</i> <i>SubformatPatternPart</i>
- *
- * <i>SubFormatPatternPart:</i>
- *         ' <i>QuotedPattern</i> '
- *         <i>UnquotedPattern</i>
  * </pre></blockquote>
  *
- * <p>
- * Within a <i>String</i>, <code>"''"</code> represents a single
- * quote. A <i>QuotedString</i> can contain arbitrary characters
- * except single quotes; the surrounding single quotes are removed.
- * An <i>UnquotedString</i> can contain arbitrary characters
- * except single quotes and left curly brackets. Thus, a string that
- * should result in the formatted message "'{0}'" can be written as
- * <code>"'''{'0}''"</code> or <code>"'''{0}'''"</code>.
- * <p>
- * Within a <i>SubformatPattern</i>, different rules apply.
- * A <i>QuotedPattern</i> can contain arbitrary characters
- * except single quotes; but the surrounding single quotes are
- * <strong>not</strong> removed, so they may be interpreted by the
- * subformat. For example, <code>"{1,number,$'#',##}"</code> will
- * produce a number format with the pound-sign quoted, with a result
- * such as: "$#31,45".
- * An <i>UnquotedPattern</i> can contain arbitrary characters
- * except single quotes, but curly braces within it must be balanced.
- * For example, <code>"ab {0} de"</code> and <code>"ab '}' de"</code>
- * are valid subformat patterns, but <code>"ab {0'}' de"</code> and
- * <code>"ab } de"</code> are not.
+ * <p>Within a <i>String</i>, a pair of single quotes can be used to
+ * quote any arbitrary characters except single quotes. For example,
+ * pattern string <code>"'{0}'"</code> represents string
+ * <code>"{0}"</code>, not a <i>FormatElement</i>. A single quote itself
+ * must be represented by doubled single quotes {@code ''} throughout a
+ * <i>String</i>.  For example, pattern string <code>"'{''}'"</code> is
+ * interpreted as a sequence of <code>'{</code> (start of quoting and a
+ * left curly brace), <code>''</code> (a single quote), and
+ * <code>}'</code> (a right curly brace and end of quoting),
+ * <em>not</em> <code>'{'</code> and <code>'}'</code> (quoted left and
+ * right curly braces): representing string <code>"{'}"</code>,
+ * <em>not</em> <code>"{}"</code>.
+ *
+ * <p>A <i>SubformatPattern</i> is interpreted by its corresponding
+ * subformat, and subformat-dependent pattern rules apply. For example,
+ * pattern string <code>"{1,number,<u>$'#',##</u>}"</code>
+ * (<i>SubformatPattern</i> with underline) will produce a number format
+ * with the pound-sign quoted, with a result such as: {@code
+ * "$#31,45"}. Refer to each {@code Format} subclass documentation for
+ * details.
+ *
+ * <p>Any unmatched quote is treated as closed at the end of the given
+ * pattern. For example, pattern string {@code "'{0}"} is treated as
+ * pattern {@code "'{0}'"}.
+ *
+ * <p>Any curly braces within an unquoted pattern must be balanced. For
+ * example, <code>"ab {0} de"</code> and <code>"ab '}' de"</code> are
+ * valid patterns, but <code>"ab {0'}' de"</code>, <code>"ab } de"</code>
+ * and <code>"''{''"</code> are not.
+ *
  * <p>
  * <dl><dt><b>Warning:</b><dd>The rules for using quotes within message
  * format patterns unfortunately have shown to be somewhat confusing.
  * In particular, it isn't always obvious to localizers whether single
  * quotes need to be doubled or not. Make sure to inform localizers about
  * the rules, and tell them (for example, by using comments in resource
- * bundle source files) which strings will be processed by MessageFormat.
+ * bundle source files) which strings will be processed by {@code MessageFormat}.
  * Note that localizers may need to use single quotes in translated
  * strings where the original version doesn't have them.
  * </dl>
  * <p>
  * The <i>ArgumentIndex</i> value is a non-negative integer written
- * using the digits '0' through '9', and represents an index into the
- * <code>arguments</code> array passed to the <code>format</code> methods
- * or the result array returned by the <code>parse</code> methods.
+ * using the digits {@code '0'} through {@code '9'}, and represents an index into the
+ * {@code arguments} array passed to the {@code format} methods
+ * or the result array returned by the {@code parse} methods.
  * <p>
  * The <i>FormatType</i> and <i>FormatStyle</i> values are used to create
- * a <code>Format</code> instance for the format element. The following
- * table shows how the values map to Format instances. Combinations not
+ * a {@code Format} instance for the format element. The following
+ * table shows how the values map to {@code Format} instances. Combinations not
  * shown in the table are illegal. A <i>SubformatPattern</i> must
- * be a valid pattern string for the Format subclass used.
+ * be a valid pattern string for the {@code Format} subclass used.
  * <p>
  * <table border=1 summary="Shows how FormatType and FormatStyle values map to Format instances">
  *    <tr>
- *       <th id="ft">Format Type
- *       <th id="fs">Format Style
- *       <th id="sc">Subformat Created
+ *       <th id="ft" class="TableHeadingColor">FormatType
+ *       <th id="fs" class="TableHeadingColor">FormatStyle
+ *       <th id="sc" class="TableHeadingColor">Subformat Created
  *    <tr>
  *       <td headers="ft"><i>(none)</i>
  *       <td headers="fs"><i>(none)</i>
@@ -167,61 +159,61 @@
  *    <tr>
  *       <td headers="ft" rowspan=5><code>number</code>
  *       <td headers="fs"><i>(none)</i>
- *       <td headers="sc"><code>NumberFormat.getInstance(getLocale())</code>
+ *       <td headers="sc">{@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())}
  *    <tr>
  *       <td headers="fs"><code>integer</code>
- *       <td headers="sc"><code>NumberFormat.getIntegerInstance(getLocale())</code>
+ *       <td headers="sc">{@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())}
  *    <tr>
  *       <td headers="fs"><code>currency</code>
- *       <td headers="sc"><code>NumberFormat.getCurrencyInstance(getLocale())</code>
+ *       <td headers="sc">{@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())}
  *    <tr>
  *       <td headers="fs"><code>percent</code>
- *       <td headers="sc"><code>NumberFormat.getPercentInstance(getLocale())</code>
+ *       <td headers="sc">{@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())}
  *    <tr>
  *       <td headers="fs"><i>SubformatPattern</i>
- *       <td headers="sc"><code>new DecimalFormat(subformatPattern, DecimalFormatSymbols.getInstance(getLocale()))</code>
+ *       <td headers="sc">{@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))}
  *    <tr>
  *       <td headers="ft" rowspan=6><code>date</code>
  *       <td headers="fs"><i>(none)</i>
- *       <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>short</code>
- *       <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.SHORT, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>medium</code>
- *       <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>long</code>
- *       <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.LONG, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>full</code>
- *       <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.FULL, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><i>SubformatPattern</i>
- *       <td headers="sc"><code>new SimpleDateFormat(subformatPattern, getLocale())</code>
+ *       <td headers="sc">{@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())}
  *    <tr>
  *       <td headers="ft" rowspan=6><code>time</code>
  *       <td headers="fs"><i>(none)</i>
- *       <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>short</code>
- *       <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>medium</code>
- *       <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>long</code>
- *       <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.LONG, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><code>full</code>
- *       <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.FULL, getLocale())</code>
+ *       <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())}
  *    <tr>
  *       <td headers="fs"><i>SubformatPattern</i>
- *       <td headers="sc"><code>new SimpleDateFormat(subformatPattern, getLocale())</code>
+ *       <td headers="sc">{@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())}
  *    <tr>
  *       <td headers="ft"><code>choice</code>
  *       <td headers="fs"><i>SubformatPattern</i>
- *       <td headers="sc"><code>new ChoiceFormat(subformatPattern)</code>
+ *       <td headers="sc">{@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)}
  * </table>
  * <p>
  *
@@ -321,7 +313,7 @@
  * </pre></blockquote>
  *
  * <p>
- * Likewise, parsing with a MessageFormat object using patterns containing
+ * Likewise, parsing with a {@code MessageFormat} object using patterns containing
  * multiple occurrences of the same argument would return the last match.  For
  * example,
  * <blockquote><pre>
@@ -343,7 +335,11 @@
  * @see          Format
  * @see          NumberFormat
  * @see          DecimalFormat
+ * @see          DecimalFormatSymbols
  * @see          ChoiceFormat
+ * @see          DateFormat
+ * @see          SimpleDateFormat
+ *
  * @author       Mark Davis
  */
 
@@ -427,18 +423,19 @@
      * @exception IllegalArgumentException if the pattern is invalid
      */
     public void applyPattern(String pattern) {
-            StringBuffer[] segments = new StringBuffer[4];
-            for (int i = 0; i < segments.length; ++i) {
-                segments[i] = new StringBuffer();
-            }
-            int part = 0;
+            StringBuilder[] segments = new StringBuilder[4];
+            // Allocate only segments[SEG_RAW] here. The rest are
+            // allocated on demand.
+            segments[SEG_RAW] = new StringBuilder();
+
+            int part = SEG_RAW;
             int formatNumber = 0;
             boolean inQuote = false;
             int braceStack = 0;
             maxOffset = -1;
             for (int i = 0; i < pattern.length(); ++i) {
                 char ch = pattern.charAt(i);
-                if (part == 0) {
+                if (part == SEG_RAW) {
                     if (ch == '\'') {
                         if (i + 1 < pattern.length()
                             && pattern.charAt(i+1) == '\'') {
@@ -448,43 +445,61 @@
                             inQuote = !inQuote;
                         }
                     } else if (ch == '{' && !inQuote) {
-                        part = 1;
+                        part = SEG_INDEX;
+                        if (segments[SEG_INDEX] == null) {
+                            segments[SEG_INDEX] = new StringBuilder();
+                        }
                     } else {
                         segments[part].append(ch);
                     }
-                } else  if (inQuote) {              // just copy quotes in parts
-                    segments[part].append(ch);
-                    if (ch == '\'') {
-                        inQuote = false;
-                    }
-                } else {
-                    switch (ch) {
-                    case ',':
-                        if (part < 3)
-                            part += 1;
-                        else
-                            segments[part].append(ch);
-                        break;
-                    case '{':
-                        ++braceStack;
+                } else  {
+                    if (inQuote) {              // just copy quotes in parts
                         segments[part].append(ch);
-                        break;
-                    case '}':
-                        if (braceStack == 0) {
-                            part = 0;
-                            makeFormat(i, formatNumber, segments);
-                            formatNumber++;
-                        } else {
-                            --braceStack;
+                        if (ch == '\'') {
+                            inQuote = false;
+                        }
+                    } else {
+                        switch (ch) {
+                        case ',':
+                            if (part < SEG_MODIFIER) {
+                                if (segments[++part] == null) {
+                                    segments[part] = new StringBuilder();
+                                }
+                            } else {
+                                segments[part].append(ch);
+                            }
+                            break;
+                        case '{':
+                            ++braceStack;
                             segments[part].append(ch);
+                            break;
+                        case '}':
+                            if (braceStack == 0) {
+                                part = SEG_RAW;
+                                makeFormat(i, formatNumber, segments);
+                                formatNumber++;
+                                // throw away other segments
+                                segments[SEG_INDEX] = null;
+                                segments[SEG_TYPE] = null;
+                                segments[SEG_MODIFIER] = null;
+                            } else {
+                                --braceStack;
+                                segments[part].append(ch);
+                            }
+                            break;
+                        case ' ':
+                            // Skip any leading space chars for SEG_TYPE.
+                            if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) {
+                                segments[part].append(ch);
+                            }
+                            break;
+                        case '\'':
+                            inQuote = true;
+                            // fall through, so we keep quotes in other parts
+                        default:
+                            segments[part].append(ch);
+                            break;
                         }
-                        break;
-                    case '\'':
-                        inQuote = true;
-                        // fall through, so we keep quotes in other parts
-                    default:
-                        segments[part].append(ch);
-                        break;
                     }
                 }
             }
@@ -506,65 +521,57 @@
     public String toPattern() {
         // later, make this more extensible
         int lastOffset = 0;
-        StringBuffer result = new StringBuffer();
+        StringBuilder result = new StringBuilder();
         for (int i = 0; i <= maxOffset; ++i) {
-            copyAndFixQuotes(pattern, lastOffset, offsets[i],result);
+            copyAndFixQuotes(pattern, lastOffset, offsets[i], result);
             lastOffset = offsets[i];
-            result.append('{');
-            result.append(argumentNumbers[i]);
-            if (formats[i] == null) {
+            result.append('{').append(argumentNumbers[i]);
+            Format fmt = formats[i];
+            if (fmt == null) {
                 // do nothing, string format
-            } else if (formats[i] instanceof DecimalFormat) {
-                if (formats[i].equals(NumberFormat.getInstance(locale))) {
+            } else if (fmt instanceof NumberFormat) {
+                if (fmt.equals(NumberFormat.getInstance(locale))) {
                     result.append(",number");
-                } else if (formats[i].equals(NumberFormat.getCurrencyInstance(locale))) {
+                } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) {
                     result.append(",number,currency");
-                } else if (formats[i].equals(NumberFormat.getPercentInstance(locale))) {
+                } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) {
                     result.append(",number,percent");
-                } else if (formats[i].equals(NumberFormat.getIntegerInstance(locale))) {
+                } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) {
                     result.append(",number,integer");
                 } else {
-                    result.append(",number," +
-                                  ((DecimalFormat)formats[i]).toPattern());
+                    if (fmt instanceof DecimalFormat) {
+                        result.append(",number,").append(((DecimalFormat)fmt).toPattern());
+                    } else if (fmt instanceof ChoiceFormat) {
+                        result.append(",choice,").append(((ChoiceFormat)fmt).toPattern());
+                    } else {
+                        // UNKNOWN
+                    }
                 }
-            } else if (formats[i] instanceof SimpleDateFormat) {
-                if (formats[i].equals(DateFormat.getDateInstance(
-                                                               DateFormat.DEFAULT,locale))) {
-                    result.append(",date");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.SHORT,locale))) {
-                    result.append(",date,short");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.DEFAULT,locale))) {
-                    result.append(",date,medium");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.LONG,locale))) {
-                    result.append(",date,long");
-                } else if (formats[i].equals(DateFormat.getDateInstance(
-                                                                      DateFormat.FULL,locale))) {
-                    result.append(",date,full");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.DEFAULT,locale))) {
-                    result.append(",time");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.SHORT,locale))) {
-                    result.append(",time,short");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.DEFAULT,locale))) {
-                    result.append(",time,medium");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.LONG,locale))) {
-                    result.append(",time,long");
-                } else if (formats[i].equals(DateFormat.getTimeInstance(
-                                                                      DateFormat.FULL,locale))) {
-                    result.append(",time,full");
-                } else {
-                    result.append(",date,"
-                                  + ((SimpleDateFormat)formats[i]).toPattern());
+            } else if (fmt instanceof DateFormat) {
+                int index;
+                for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) {
+                    DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index],
+                                                               locale);
+                    if (fmt.equals(df)) {
+                        result.append(",date");
+                        break;
+                    }
+                    df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index],
+                                                    locale);
+                    if (fmt.equals(df)) {
+                        result.append(",time");
+                        break;
+                    }
                 }
-            } else if (formats[i] instanceof ChoiceFormat) {
-                result.append(",choice,"
-                              + ((ChoiceFormat)formats[i]).toPattern());
+                if (index >= DATE_TIME_MODIFIERS.length) {
+                    if (fmt instanceof SimpleDateFormat) {
+                        result.append(",date,").append(((SimpleDateFormat)fmt).toPattern());
+                    } else {
+                        // UNKNOWN
+                    }
+                } else if (index != MODIFIER_DEFAULT) {
+                    result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]);
+                }
             } else {
                 //result.append(", unknown");
             }
@@ -678,7 +685,7 @@
      *
      * @param formatElementIndex the index of a format element within the pattern
      * @param newFormat the format to use for the specified format element
-     * @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or
+     * @exception ArrayIndexOutOfBoundsException if {@code formatElementIndex} is equal to or
      *            larger than the number of format elements in the pattern string
      */
     public void setFormat(int formatElementIndex, Format newFormat) {
@@ -972,7 +979,8 @@
                 if (patternOffset >= tempLength) {
                     next = source.length();
                 }else{
-                    next = source.indexOf( pattern.substring(patternOffset,tempLength), sourceOffset);
+                    next = source.indexOf(pattern.substring(patternOffset, tempLength),
+                                          sourceOffset);
                 }
 
                 if (next < 0) {
@@ -1226,7 +1234,7 @@
             lastOffset = offsets[i];
             int argumentNumber = argumentNumbers[i];
             if (arguments == null || argumentNumber >= arguments.length) {
-                result.append("{" + argumentNumber + "}");
+                result.append('{').append(argumentNumber).append('}');
                 continue;
             }
             // int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3);
@@ -1338,25 +1346,83 @@
         }
     }
 
-    private static final String[] typeList =
-    {"", "", "number", "", "date", "", "time", "", "choice"};
-    private static final String[] modifierList =
-    {"", "", "currency", "", "percent", "", "integer"};
-    private static final String[] dateModifierList =
-    {"", "", "short", "", "medium", "", "long", "", "full"};
+    // Indices for segments
+    private static final int SEG_RAW      = 0;
+    private static final int SEG_INDEX    = 1;
+    private static final int SEG_TYPE     = 2;
+    private static final int SEG_MODIFIER = 3; // modifier or subformat
+
+    // Indices for type keywords
+    private static final int TYPE_NULL    = 0;
+    private static final int TYPE_NUMBER  = 1;
+    private static final int TYPE_DATE    = 2;
+    private static final int TYPE_TIME    = 3;
+    private static final int TYPE_CHOICE  = 4;
+
+    private static final String[] TYPE_KEYWORDS = {
+        "",
+        "number",
+        "date",
+        "time",
+        "choice"
+    };
+
+    // Indices for number modifiers
+    private static final int MODIFIER_DEFAULT  = 0; // common in number and date-time
+    private static final int MODIFIER_CURRENCY = 1;
+    private static final int MODIFIER_PERCENT  = 2;
+    private static final int MODIFIER_INTEGER  = 3;
+
+    private static final String[] NUMBER_MODIFIER_KEYWORDS = {
+        "",
+        "currency",
+        "percent",
+        "integer"
+    };
+
+    // Indices for date-time modifiers
+    private static final int MODIFIER_SHORT   = 1;
+    private static final int MODIFIER_MEDIUM  = 2;
+    private static final int MODIFIER_LONG    = 3;
+    private static final int MODIFIER_FULL    = 4;
+
+    private static final String[] DATE_TIME_MODIFIER_KEYWORDS = {
+        "",
+        "short",
+        "medium",
+        "long",
+        "full"
+    };
+
+    // Date-time style values corresponding to the date-time modifiers.
+    private static final int[] DATE_TIME_MODIFIERS = {
+        DateFormat.DEFAULT,
+        DateFormat.SHORT,
+        DateFormat.MEDIUM,
+        DateFormat.LONG,
+        DateFormat.FULL,
+    };
 
     private void makeFormat(int position, int offsetNumber,
-                            StringBuffer[] segments)
+                            StringBuilder[] textSegments)
     {
+        String[] segments = new String[textSegments.length];
+        for (int i = 0; i < textSegments.length; i++) {
+            StringBuilder oneseg = textSegments[i];
+            segments[i] = (oneseg != null) ? oneseg.toString() : "";
+        }
+
         // get the argument number
         int argumentNumber;
         try {
-            argumentNumber = Integer.parseInt(segments[1].toString()); // always unlocalized!
+            argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always unlocalized!
         } catch (NumberFormatException e) {
-            throw new IllegalArgumentException("can't parse argument number: " + segments[1]);
+            throw new IllegalArgumentException("can't parse argument number: "
+                                               + segments[SEG_INDEX], e);
         }
         if (argumentNumber < 0) {
-            throw new IllegalArgumentException("negative argument number: " + argumentNumber);
+            throw new IllegalArgumentException("negative argument number: "
+                                               + argumentNumber);
         }
 
         // resize format information arrays if necessary
@@ -1374,120 +1440,129 @@
         }
         int oldMaxOffset = maxOffset;
         maxOffset = offsetNumber;
-        offsets[offsetNumber] = segments[0].length();
+        offsets[offsetNumber] = segments[SEG_RAW].length();
         argumentNumbers[offsetNumber] = argumentNumber;
 
         // now get the format
         Format newFormat = null;
-        switch (findKeyword(segments[2].toString(), typeList)) {
-        case 0:
-            break;
-        case 1: case 2:// number
-            switch (findKeyword(segments[3].toString(), modifierList)) {
-            case 0: // default;
-                newFormat = NumberFormat.getInstance(locale);
+        if (segments[SEG_TYPE].length() != 0) {
+            int type = findKeyword(segments[SEG_TYPE], TYPE_KEYWORDS);
+            switch (type) {
+            case TYPE_NULL:
+                // Type "" is allowed. e.g., "{0,}", "{0,,}", and "{0,,#}"
+                // are treated as "{0}".
                 break;
-            case 1: case 2:// currency
-                newFormat = NumberFormat.getCurrencyInstance(locale);
-                break;
-            case 3: case 4:// percent
-                newFormat = NumberFormat.getPercentInstance(locale);
-                break;
-            case 5: case 6:// integer
-                newFormat = NumberFormat.getIntegerInstance(locale);
-                break;
-            default: // pattern
-                newFormat = new DecimalFormat(segments[3].toString(), DecimalFormatSymbols.getInstance(locale));
+
+            case TYPE_NUMBER:
+                switch (findKeyword(segments[SEG_MODIFIER], NUMBER_MODIFIER_KEYWORDS)) {
+                case MODIFIER_DEFAULT:
+                    newFormat = NumberFormat.getInstance(locale);
+                    break;
+                case MODIFIER_CURRENCY:
+                    newFormat = NumberFormat.getCurrencyInstance(locale);
+                    break;
+                case MODIFIER_PERCENT:
+                    newFormat = NumberFormat.getPercentInstance(locale);
+                    break;
+                case MODIFIER_INTEGER:
+                    newFormat = NumberFormat.getIntegerInstance(locale);
+                    break;
+                default: // DecimalFormat pattern
+                    try {
+                        newFormat = new DecimalFormat(segments[SEG_MODIFIER],
+                                                      DecimalFormatSymbols.getInstance(locale));
+                    } catch (IllegalArgumentException e) {
+                        maxOffset = oldMaxOffset;
+                        throw e;
+                    }
+                    break;
+                }
                 break;
-            }
-            break;
-        case 3: case 4: // date
-            switch (findKeyword(segments[3].toString(), dateModifierList)) {
-            case 0: // default
-                newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
-                break;
-            case 1: case 2: // short
-                newFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+
+            case TYPE_DATE:
+            case TYPE_TIME:
+                int mod = findKeyword(segments[SEG_MODIFIER], DATE_TIME_MODIFIER_KEYWORDS);
+                if (mod >= 0 && mod < DATE_TIME_MODIFIER_KEYWORDS.length) {
+                    if (type == TYPE_DATE) {
+                        newFormat = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[mod],
+                                                               locale);
+                    } else {
+                        newFormat = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[mod],
+                                                               locale);
+                    }
+                } else {
+                    // SimpleDateFormat pattern
+                    try {
+                        newFormat = new SimpleDateFormat(segments[SEG_MODIFIER], locale);
+                    } catch (IllegalArgumentException e) {
+                        maxOffset = oldMaxOffset;
+                        throw e;
+                    }
+                }
                 break;
-            case 3: case 4: // medium
-                newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
+
+            case TYPE_CHOICE:
+                try {
+                    // ChoiceFormat pattern
+                    newFormat = new ChoiceFormat(segments[SEG_MODIFIER]);
+                } catch (Exception e) {
+                    maxOffset = oldMaxOffset;
+                    throw new IllegalArgumentException("Choice Pattern incorrect: "
+                                                       + segments[SEG_MODIFIER], e);
+                }
                 break;
-            case 5: case 6: // long
-                newFormat = DateFormat.getDateInstance(DateFormat.LONG, locale);
-                break;
-            case 7: case 8: // full
-                newFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);
-                break;
+
             default:
-                newFormat = new SimpleDateFormat(segments[3].toString(), locale);
-                break;
+                maxOffset = oldMaxOffset;
+                throw new IllegalArgumentException("unknown format type: " +
+                                                   segments[SEG_TYPE]);
             }
-            break;
-        case 5: case 6:// time
-            switch (findKeyword(segments[3].toString(), dateModifierList)) {
-            case 0: // default
-                newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
-                break;
-            case 1: case 2: // short
-                newFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
-                break;
-            case 3: case 4: // medium
-                newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
-                break;
-            case 5: case 6: // long
-                newFormat = DateFormat.getTimeInstance(DateFormat.LONG, locale);
-                break;
-            case 7: case 8: // full
-                newFormat = DateFormat.getTimeInstance(DateFormat.FULL, locale);
-                break;
-            default:
-                newFormat = new SimpleDateFormat(segments[3].toString(), locale);
-                break;
-            }
-            break;
-        case 7: case 8:// choice
-            try {
-                newFormat = new ChoiceFormat(segments[3].toString());
-            } catch (Exception e) {
-                maxOffset = oldMaxOffset;
-                throw new IllegalArgumentException(
-                                         "Choice Pattern incorrect");
-            }
-            break;
-        default:
-            maxOffset = oldMaxOffset;
-            throw new IllegalArgumentException("unknown format type: " +
-                                               segments[2].toString());
         }
         formats[offsetNumber] = newFormat;
-        segments[1].setLength(0);   // throw away other segments
-        segments[2].setLength(0);
-        segments[3].setLength(0);
     }
 
     private static final int findKeyword(String s, String[] list) {
-        s = s.trim().toLowerCase();
         for (int i = 0; i < list.length; ++i) {
             if (s.equals(list[i]))
                 return i;
         }
+
+        // Try trimmed lowercase.
+        String ls = s.trim().toLowerCase(Locale.ROOT);
+        if (ls != s) {
+            for (int i = 0; i < list.length; ++i) {
+                if (ls.equals(list[i]))
+                    return i;
+            }
+        }
         return -1;
     }
 
-    private static final void copyAndFixQuotes(
-                                               String source, int start, int end, StringBuffer target) {
+    private static final void copyAndFixQuotes(String source, int start, int end,
+                                               StringBuilder target) {
+        boolean quoted = false;
+
         for (int i = start; i < end; ++i) {
             char ch = source.charAt(i);
             if (ch == '{') {
-                target.append("'{'");
-            } else if (ch == '}') {
-                target.append("'}'");
+                if (!quoted) {
+                    target.append('\'');
+                    quoted = true;
+                }
+                target.append(ch);
             } else if (ch == '\'') {
                 target.append("''");
             } else {
+                if (quoted) {
+                    target.append('\'');
+                    quoted = false;
+                }
                 target.append(ch);
             }
         }
+        if (quoted) {
+            target.append('\'');
+        }
     }
 
     /**
--- a/jdk/src/share/classes/java/text/SimpleDateFormat.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/text/SimpleDateFormat.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1663,6 +1663,81 @@
     }
 
     /**
+     * Parses numeric forms of time zone offset, such as "hh:mm", and
+     * sets calb to the parsed value.
+     *
+     * @param text  the text to be parsed
+     * @param start the character position to start parsing
+     * @param sign  1: positive; -1: negative
+     * @param count 0: 'Z' or "GMT+hh:mm" parsing; 1 - 3: the number of 'X's
+     * @param colon true - colon required between hh and mm; false - no colon required
+     * @param calb  a CalendarBuilder in which the parsed value is stored
+     * @return updated parsed position, or its negative value to indicate a parsing error
+     */
+    private int subParseNumericZone(String text, int start, int sign, int count,
+                                    boolean colon, CalendarBuilder calb) {
+        int index = start;
+
+      parse:
+        try {
+            char c = text.charAt(index++);
+            // Parse hh
+            int hours;
+            if (!isDigit(c)) {
+                break parse;
+            }
+            hours = c - '0';
+            c = text.charAt(index++);
+            if (isDigit(c)) {
+                hours = hours * 10 + (c - '0');
+            } else {
+                // If no colon in RFC 822 or 'X' (ISO), two digits are
+                // required.
+                if (count > 0 || !colon) {
+                    break parse;
+                }
+                --index;
+            }
+            if (hours > 23) {
+                break parse;
+            }
+            int minutes = 0;
+            if (count != 1) {
+                // Proceed with parsing mm
+                c = text.charAt(index++);
+                if (colon) {
+                    if (c != ':') {
+                        break parse;
+                    }
+                    c = text.charAt(index++);
+                }
+                if (!isDigit(c)) {
+                    break parse;
+                }
+                minutes = c - '0';
+                c = text.charAt(index++);
+                if (!isDigit(c)) {
+                    break parse;
+                }
+                minutes = minutes * 10 + (c - '0');
+                if (minutes > 59) {
+                    break parse;
+                }
+            }
+            minutes += hours * 60;
+            calb.set(Calendar.ZONE_OFFSET, minutes * MILLIS_PER_MINUTE * sign)
+                .set(Calendar.DST_OFFSET, 0);
+            return index;
+        } catch (IndexOutOfBoundsException e) {
+        }
+        return  1 - index; // -(index - 1)
+    }
+
+    private boolean isDigit(char c) {
+        return c >= '0' && c <= '9';
+    }
+
+    /**
      * Private member function that converts the parsed date strings into
      * timeFields. Returns -start (for ParsePosition) if failed.
      * @param text the time text to be parsed.
@@ -1907,248 +1982,95 @@
 
             case PATTERN_ZONE_NAME:  // 'z'
             case PATTERN_ZONE_VALUE: // 'Z'
-                // First try to parse generic forms such as GMT-07:00. Do this first
-                // in case localized TimeZoneNames contains the string "GMT"
-                // for a zone; in that case, we don't want to match the first three
-                // characters of GMT+/-hh:mm etc.
                 {
                     int sign = 0;
-                    int offset;
-
-                    // For time zones that have no known names, look for strings
-                    // of the form:
-                    //    GMT[+-]hours:minutes or
-                    //    GMT.
-                    if ((text.length() - start) >= GMT.length() &&
-                        text.regionMatches(true, start, GMT, 0, GMT.length())) {
-                        int num;
-                        calb.set(Calendar.DST_OFFSET, 0);
-                        pos.index = start + GMT.length();
-
-                        try { // try-catch for "GMT" only time zone string
-                            char c = text.charAt(pos.index);
-                            if (c == '+') {
-                                sign = 1;
-                            } else if (c == '-') {
-                                sign = -1;
-                            }
+                    try {
+                        char c = text.charAt(pos.index);
+                        if (c == '+') {
+                            sign = 1;
+                        } else if (c == '-') {
+                            sign = -1;
                         }
-                        catch(StringIndexOutOfBoundsException e) {}
-
-                        if (sign == 0) {    /* "GMT" without offset */
-                            calb.set(Calendar.ZONE_OFFSET, 0);
-                            return pos.index;
-                        }
+                        if (sign == 0) {
+                            // Try parsing a custom time zone "GMT+hh:mm" or "GMT".
+                            if ((c == 'G' || c == 'g')
+                                && (text.length() - start) >= GMT.length()
+                                && text.regionMatches(true, start, GMT, 0, GMT.length())) {
+                                pos.index = start + GMT.length();
 
-                        // Look for hours.
-                        try {
-                            char c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            num = c - '0';
-
-                            if (text.charAt(++pos.index) != ':') {
-                                c = text.charAt(pos.index);
-                                if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                    break parsing;
+                                if ((text.length() - pos.index) > 0) {
+                                    c = text.charAt(pos.index);
+                                    if (c == '+') {
+                                        sign = 1;
+                                    } else if (c == '-') {
+                                        sign = -1;
+                                    }
                                 }
-                                num *= 10;
-                                num += c - '0';
-                                pos.index++;
-                            }
-                            if (num > 23) {
-                                --pos.index;
-                                break parsing;
-                            }
-                            if  (text.charAt(pos.index) != ':') {
-                                break parsing;
-                            }
 
-                            // Look for minutes.
-                            offset = num * 60;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            num = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            num *= 10;
-                            num += c - '0';
+                                if (sign == 0) {    /* "GMT" without offset */
+                                    calb.set(Calendar.ZONE_OFFSET, 0)
+                                        .set(Calendar.DST_OFFSET, 0);
+                                    return pos.index;
+                                }
 
-                            if (num > 59) {
-                                break parsing;
-                            }
-                        } catch (StringIndexOutOfBoundsException e) {
-                            break parsing;
-                        }
-                        offset += num;
-                        // Fall through for final processing below of 'offset' and 'sign'.
-                    } else {
-                        // If the first character is a sign, look for numeric timezones of
-                        // the form [+-]hhmm as specified by RFC 822. Otherwise, check
-                        // for named time zones by looking through the locale data from
-                        // the TimeZoneNames strings.
-                        try {
-                            char c = text.charAt(pos.index);
-                            if (c == '+') {
-                                sign = 1;
-                            } else if (c == '-') {
-                                sign = -1;
-                            } else {
-                                // Try parsing the text as a time zone name (abbr).
-                                int i = subParseZoneString(text, pos.index, calb);
-                                if (i != 0) {
+                                // Parse the rest as "hh:mm"
+                                int i = subParseNumericZone(text, ++pos.index,
+                                                            sign, 0, true, calb);
+                                if (i > 0) {
                                     return i;
                                 }
-                                break parsing;
-                            }
-
-                            // Parse the text as an RFC 822 time zone string. This code is
-                            // actually a little more permissive than RFC 822.  It will
-                            // try to do its best with numbers that aren't strictly 4
-                            // digits long.
-
-                            // Look for hh.
-                            int hours = 0;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours *= 10;
-                            hours += c - '0';
-
-                            if (hours > 23) {
-                                break parsing;
+                                pos.index = -i;
+                            } else {
+                                // Try parsing the text as a time zone
+                                // name or abbreviation.
+                                int i = subParseZoneString(text, pos.index, calb);
+                                if (i > 0) {
+                                    return i;
+                                }
+                                pos.index = -i;
                             }
-
-                            // Look for mm.
-                            int minutes = 0;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            minutes = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
+                        } else {
+                            // Parse the rest as "hhmm" (RFC 822)
+                            int i = subParseNumericZone(text, ++pos.index,
+                                                        sign, 0, false, calb);
+                            if (i > 0) {
+                                return i;
                             }
-                            minutes *= 10;
-                            minutes += c - '0';
-
-                            if (minutes > 59) {
-                                break parsing;
-                            }
-
-                            offset = hours * 60 + minutes;
-                        } catch (StringIndexOutOfBoundsException e) {
-                            break parsing;
+                            pos.index = -i;
                         }
-                    }
-
-                    // Do the final processing for both of the above cases.  We only
-                    // arrive here if the form GMT+/-... or an RFC 822 form was seen.
-                    if (sign != 0) {
-                        offset *= MILLIS_PER_MINUTE * sign;
-                        calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
-                        return ++pos.index;
+                    } catch (IndexOutOfBoundsException e) {
                     }
                 }
                 break parsing;
 
             case PATTERN_ISO_ZONE:   // 'X'
                 {
-                    int sign = 0;
-                    int offset = 0;
-
-                    iso8601: {
-                        try {
-                            char c = text.charAt(pos.index);
-                            if (c == 'Z') {
-                                calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
-                                return ++pos.index;
-                            }
-
-                            // parse text as "+/-hh[[:]mm]" based on count
-                            if (c == '+') {
-                                sign = 1;
-                            } else if (c == '-') {
-                                sign = -1;
-                            }
-                            // Look for hh.
-                            int hours = 0;
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            hours *= 10;
-                            hours += c - '0';
-                            if (hours > 23) {
-                                break parsing;
-                            }
+                    if ((text.length() - pos.index) <= 0) {
+                        break parsing;
+                    }
 
-                            if (count == 1) { // "X"
-                                offset = hours * 60;
-                                break iso8601;
-                            }
-
-                            c = text.charAt(++pos.index);
-                            // Skip ':' if "XXX"
-                            if (c == ':') {
-                                if (count == 2) {
-                                    break parsing;
-                                }
-                                c = text.charAt(++pos.index);
-                            } else {
-                                if (count == 3) {
-                                    // missing ':'
-                                    break parsing;
-                                }
-                            }
-
-                            // Look for mm.
-                            int minutes = 0;
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            minutes = c - '0';
-                            c = text.charAt(++pos.index);
-                            if (c < '0' || c > '9') { /* must be from '0' to '9'. */
-                                break parsing;
-                            }
-                            minutes *= 10;
-                            minutes += c - '0';
-
-                            if (minutes > 59) {
-                                break parsing;
-                            }
-
-                            offset = hours * 60 + minutes;
-                        } catch (StringIndexOutOfBoundsException e) {
-                            break parsing;
-                        }
+                    int sign = 0;
+                    char c = text.charAt(pos.index);
+                    if (c == 'Z') {
+                        calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
+                        return ++pos.index;
                     }
 
-                    // Do the final processing for both of the above cases.  We only
-                    // arrive here if the form GMT+/-... or an RFC 822 form was seen.
-                    if (sign != 0) {
-                        offset *= MILLIS_PER_MINUTE * sign;
-                        calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
-                        return ++pos.index;
+                    // parse text as "+/-hh[[:]mm]" based on count
+                    if (c == '+') {
+                        sign = 1;
+                    } else if (c == '-') {
+                        sign = -1;
+                    } else {
+                        ++pos.index;
+                        break parsing;
                     }
+                    int i = subParseNumericZone(text, ++pos.index, sign, count,
+                                                count == 3, calb);
+                    if (i > 0) {
+                        return i;
+                    }
+                    pos.index = -i;
                 }
                 break parsing;
 
--- a/jdk/src/share/classes/java/util/Locale.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/java/util/Locale.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1449,10 +1449,15 @@
      * three-letter language abbreviation is not available for this locale.
      */
     public String getISO3Language() throws MissingResourceException {
-        String language3 = getISO3Code(_baseLocale.getLanguage(), LocaleISOData.isoLanguageTable);
+        String lang = _baseLocale.getLanguage();
+        if (lang.length() == 3) {
+            return lang;
+        }
+
+        String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
         if (language3 == null) {
             throw new MissingResourceException("Couldn't find 3-letter language code for "
-                    + _baseLocale.getLanguage(), "FormatData_" + toString(), "ShortLanguage");
+                    + lang, "FormatData_" + toString(), "ShortLanguage");
         }
         return language3;
     }
--- a/jdk/src/share/classes/javax/print/attribute/standard/DialogTypeSelection.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/print/attribute/standard/DialogTypeSelection.java	Wed Jan 19 19:00:30 2011 -0800
@@ -52,6 +52,8 @@
 public final class DialogTypeSelection extends EnumSyntax
         implements PrintRequestAttribute {
 
+    private static final long serialVersionUID = 7518682952133256029L;
+
     /**
      *
      */
--- a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java	Wed Jan 19 19:00:30 2011 -0800
@@ -310,7 +310,7 @@
         } else {
             transmitter = device.getTransmitter();
         }
-        if (!(transmitter instanceof MidiDeviceReceiver)) {
+        if (!(transmitter instanceof MidiDeviceTransmitter)) {
             transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter);
         }
         return transmitter;
--- a/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java	Wed Jan 19 19:00:30 2011 -0800
@@ -359,7 +359,22 @@
                         f.getWidth()-1, f.getHeight()-1);
               }
               g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);
-              currentLoc = new Point (newX, newY);
+              /* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.
+              * Swing doesn't expect that its XOR drawRect did
+              * not complete, so believes that on re-entering at
+              * the next update location, that there is an XOR rect
+              * to draw out at "currentLoc". But in fact
+              * its now got a new clean surface without that rect,
+              * so drawing it "out" in fact draws it on, leaving garbage.
+              * So only update/set currentLoc if the draw completed.
+              */
+              sun.java2d.SurfaceData sData =
+                  ((sun.java2d.SunGraphics2D)g).getSurfaceData();
+
+              if (!sData.isSurfaceLost()) {
+                  currentLoc = new Point (newX, newY);
+              }
+;
               g.dispose();
             }
         } else if (dragMode == FASTER_DRAG_MODE) {
@@ -412,7 +427,14 @@
                 g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);
               }
               g.drawRect( newX, newY, newWidth-1, newHeight-1);
-              currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
+
+              // Work around for 6635462, see comment in dragFrame()
+              sun.java2d.SurfaceData sData =
+                  ((sun.java2d.SunGraphics2D)g).getSurfaceData();
+              if (!sData.isSurfaceLost()) {
+                  currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
+              }
+
               g.setPaintMode();
               g.dispose();
             }
--- a/jdk/src/share/classes/javax/swing/JSlider.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/swing/JSlider.java	Wed Jan 19 19:00:30 2011 -0800
@@ -40,7 +40,8 @@
 
 /**
  * A component that lets the user graphically select a value by sliding
- * a knob within a bounded interval.
+ * a knob within a bounded interval. The knob is always positioned
+ * at the points that match integer values within the specified interval.
  * <p>
  * The slider can show both
  * major tick marks, and minor tick marks between the major ones.  The number of
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSpinnerUI.java	Wed Jan 19 19:00:30 2011 -0800
@@ -908,6 +908,14 @@
             int height = parent.getHeight();
 
             Insets insets = parent.getInsets();
+
+            if (nextButton == null && previousButton == null) {
+                setBounds(editor, insets.left,  insets.top, width - insets.left - insets.right,
+                        height - insets.top - insets.bottom);
+
+                return;
+            }
+
             Dimension nextD = preferredSize(nextButton);
             Dimension previousD = preferredSize(previousButton);
             int buttonsWidth = Math.max(nextD.width, previousD.width);
--- a/jdk/src/share/classes/sun/awt/FontConfiguration.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/awt/FontConfiguration.java	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,10 +37,10 @@
 import java.nio.charset.CharsetEncoder;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map.Entry;
 import java.util.Properties;
@@ -329,6 +329,8 @@
      * tables.
      */
     public static void saveBinary(OutputStream out) throws IOException {
+        sanityCheck();
+
         DataOutputStream dataOut = new DataOutputStream(out);
         writeShortTable(dataOut, head);
         writeShortTable(dataOut, table_scriptIDs);
@@ -350,7 +352,6 @@
         if (verbose) {
             dump();
         }
-        sanityCheck();
     }
 
     //private static boolean loadingProperties;
@@ -1343,6 +1344,11 @@
     private static short[] table_stringIDs;
     private static char[]  table_stringTable;
 
+    /**
+     * Checks consistencies of complied fontconfig data. This method
+     * is called only at the build-time from
+     * build.tools.compilefontconfig.CompileFontConfig.
+     */
     private static void sanityCheck() {
         int errors = 0;
 
@@ -1358,12 +1364,20 @@
         //componentFontNameID starts from "1"
         for (int ii = 1; ii < table_filenames.length; ii++) {
             if (table_filenames[ii] == -1) {
-                System.out.println("\n Warning: "
-                                   + "<filename."
-                                   + getString(table_componentFontNameIDs[ii])
-                                   + "> entry is missing!!!");
-                if (!osName.contains("Linux")) {
+                // The corresponding finename entry for a component
+                // font name is mandatory on Windows, but it's
+                // optional on Solaris and Linux.
+                if (osName.contains("Windows")) {
+                    System.err.println("\n Error: <filename."
+                                       + getString(table_componentFontNameIDs[ii])
+                                       + "> entry is missing!!!");
                     errors++;
+                } else {
+                    if (verbose && !isEmpty(table_filenames)) {
+                        System.err.println("\n Note: 'filename' entry is undefined for \""
+                                           + getString(table_componentFontNameIDs[ii])
+                                           + "\"");
+                    }
                 }
             }
         }
@@ -1382,7 +1396,7 @@
                         int jj = iii * NUM_STYLES + iij;
                         short ffid = table_scriptFonts[fid + jj];
                         if (ffid == 0) {
-                            System.out.println("\n Error: <"
+                            System.err.println("\n Error: <"
                                            + getFontName(iii) + "."
                                            + getStyleName(iij) + "."
                                            + getString(table_scriptIDs[ii])
@@ -1402,7 +1416,7 @@
                         script.contains("symbol")) {
                         continue;
                     }
-                    System.out.println("\nError: "
+                    System.err.println("\nError: "
                                        + "<awtfontpath."
                                        + script
                                        + "> entry is missing!!!");
@@ -1411,11 +1425,19 @@
             }
         }
         if (errors != 0) {
-            System.out.println("!!THERE ARE " + errors + " ERROR(S) IN "
+            System.err.println("!!THERE ARE " + errors + " ERROR(S) IN "
                                + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n");
             System.exit(1);
+        }
+    }
 
+    private static boolean isEmpty(short[] a) {
+        for (short s : a) {
+            if (s != -1) {
+                return false;
+            }
         }
+        return true;
     }
 
     //dump the fontconfig data tables
@@ -1652,20 +1674,16 @@
 
     private static void writeShortTable(DataOutputStream out, short[] data)
         throws IOException {
-        for (int i = 0; i < data.length; i++) {
-            out.writeShort(data[i]);
+        for (short val : data) {
+            out.writeShort(val);
         }
     }
 
-    private static short[] toList(HashMap map) {
+    private static short[] toList(HashMap<String, Short> map) {
         short[] list = new short[map.size()];
-        for (int i = 0; i < list.length; i++) {
-            list[i] = -1;
-        }
-        Iterator iterator = map.entrySet().iterator();
-        while (iterator.hasNext()) {
-            Entry<String, Short> entry = (Entry <String, Short>)iterator.next();
-            list[entry.getValue().shortValue()] = getStringID(entry.getKey());
+        Arrays.fill(list, (short) -1);
+        for (Entry<String, Short> entry : map.entrySet()) {
+            list[entry.getValue()] = getStringID(entry.getKey());
         }
         return list;
     }
@@ -1763,25 +1781,19 @@
             int len = table_scriptIDs.length + scriptFonts.size() * 20;
             table_scriptFonts = new short[len];
 
-            Iterator iterator = scriptAllfonts.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
-                table_scriptFonts[entry.getKey().intValue()] = (short)entry.getValue().shortValue();
+            for (Entry<Short, Short> entry : scriptAllfonts.entrySet()) {
+                table_scriptFonts[entry.getKey().intValue()] = entry.getValue();
             }
             int off = table_scriptIDs.length;
-            iterator = scriptFonts.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
+            for (Entry<Short, Short[]> entry : scriptFonts.entrySet()) {
                 table_scriptFonts[entry.getKey().intValue()] = (short)-off;
                 Short[] v = entry.getValue();
-                int i = 0;
-                while (i < 20) {
+                for (int i = 0; i < 20; i++) {
                     if (v[i] != null) {
-                        table_scriptFonts[off++] = v[i].shortValue();
+                        table_scriptFonts[off++] = v[i];
                     } else {
                         table_scriptFonts[off++] = 0;
                     }
-                    i++;
                 }
             }
 
@@ -1792,9 +1804,7 @@
             //(3) sequences  elcID -> XXXX[1|5] -> scriptID[]
             head[INDEX_sequences] = (short)(head[INDEX_elcIDs]  + table_elcIDs.length);
             table_sequences = new short[elcIDs.size() * NUM_FONTS];
-            iterator = sequences.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Entry<Short, short[]> entry = (Entry <Short, short[]>)iterator.next();
+            for (Entry<Short, short[]> entry : sequences.entrySet()) {
                 //table_sequences[entry.getKey().intValue()] = (short)-off;
                 int k = entry.getKey().intValue();
                 short[] v = entry.getValue();
@@ -1827,31 +1837,24 @@
             //(6)componentFontNameID -> filenameID
             head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs]  + table_componentFontNameIDs.length);
             table_filenames = new short[table_componentFontNameIDs.length];
-            for (int i = 0; i < table_filenames.length; i++) {
-                table_filenames[i] = -1;
-            }
-            iterator = filenames.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
-                table_filenames[entry.getKey().shortValue()] = entry.getValue().shortValue();
+            Arrays.fill(table_filenames, (short) -1);
+
+            for (Entry<Short, Short> entry : filenames.entrySet()) {
+                table_filenames[entry.getKey()] = entry.getValue();
             }
 
             //(7)scriptID-> awtfontpath
             //the paths are stored as scriptID -> stringID in awtfontpahts
             head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames]  + table_filenames.length);
             table_awtfontpaths = new short[table_scriptIDs.length];
-            iterator = awtfontpaths.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
-                table_awtfontpaths[entry.getKey().shortValue()] = entry.getValue().shortValue();
+            for (Entry<Short, Short> entry : awtfontpaths.entrySet()) {
+                table_awtfontpaths[entry.getKey()] = entry.getValue();
             }
 
             //(8)exclusions
             head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths]  + table_awtfontpaths.length);
             table_exclusions = new short[scriptIDs.size()];
-            iterator = exclusions.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Entry<Short, int[]> entry = (Entry <Short, int[]>)iterator.next();
+            for (Entry<Short, int[]> entry : exclusions.entrySet()) {
                 int[] exI = entry.getValue();
                 char[] exC = new char[exI.length * 2];
                 int j = 0;
@@ -1859,17 +1862,15 @@
                     exC[j++] = (char) (exI[i] >> 16);
                     exC[j++] = (char) (exI[i] & 0xffff);
                 }
-                table_exclusions[entry.getKey().shortValue()] = getStringID(new String (exC));
+                table_exclusions[entry.getKey()] = getStringID(new String (exC));
             }
             //(9)proportionals
             head[INDEX_proportionals] = (short)(head[INDEX_exclusions]  + table_exclusions.length);
             table_proportionals = new short[proportionals.size() * 2];
-            iterator = proportionals.entrySet().iterator();
             int j = 0;
-            while (iterator.hasNext()) {
-                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
-                table_proportionals[j++] = entry.getKey().shortValue();
-                table_proportionals[j++] = entry.getValue().shortValue();
+            for (Entry<Short, Short> entry : proportionals.entrySet()) {
+                table_proportionals[j++] = entry.getKey();
+                table_proportionals[j++] = entry.getValue();
             }
 
             //(10) see (1) for info, the only difference is "xxx.motif"
@@ -1878,22 +1879,18 @@
                 len = table_scriptIDs.length + scriptFontsMotif.size() * 20;
                 table_scriptFontsMotif = new short[len];
 
-                iterator = scriptAllfontsMotif.entrySet().iterator();
-                while (iterator.hasNext()) {
-                    Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
+                for (Entry<Short, Short> entry : scriptAllfontsMotif.entrySet()) {
                     table_scriptFontsMotif[entry.getKey().intValue()] =
-                      (short)entry.getValue().shortValue();
+                      (short)entry.getValue();
                 }
                 off = table_scriptIDs.length;
-                iterator = scriptFontsMotif.entrySet().iterator();
-                while (iterator.hasNext()) {
-                    Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
+                for (Entry<Short, Short[]> entry : scriptFontsMotif.entrySet()) {
                     table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off;
                     Short[] v = entry.getValue();
                     int i = 0;
                     while (i < 20) {
                         if (v[i] != null) {
-                            table_scriptFontsMotif[off++] = v[i].shortValue();
+                            table_scriptFontsMotif[off++] = v[i];
                         } else {
                             table_scriptFontsMotif[off++] = 0;
                         }
@@ -1907,12 +1904,10 @@
             //(11)short[] alphabeticSuffix
             head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length);
             table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2];
-            iterator = alphabeticSuffix.entrySet().iterator();
             j = 0;
-            while (iterator.hasNext()) {
-                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
-                table_alphabeticSuffix[j++] = entry.getKey().shortValue();
-                table_alphabeticSuffix[j++] = entry.getValue().shortValue();
+            for (Entry<Short, Short> entry : alphabeticSuffix.entrySet()) {
+                table_alphabeticSuffix[j++] = entry.getKey();
+                table_alphabeticSuffix[j++] = entry.getValue();
             }
 
             //(15)short[] fallbackScriptIDs; just put the ID in head
--- a/jdk/src/share/classes/sun/awt/SunToolkit.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/awt/SunToolkit.java	Wed Jan 19 19:00:30 2011 -0800
@@ -102,26 +102,6 @@
     public final static int MAX_BUTTONS_SUPPORTED = 20;
 
     public SunToolkit() {
-        /* If awt.threadgroup is set to class name the instance of
-         * this class is created (should be subclass of ThreadGroup)
-         * and EventDispatchThread is created inside of it
-         *
-         * If loaded class overrides uncaughtException instance
-         * handles all uncaught exception on EventDispatchThread
-         */
-        ThreadGroup threadGroup = null;
-        String tgName = System.getProperty("awt.threadgroup", "");
-
-        if (tgName.length() != 0) {
-            try {
-                Constructor ctor = Class.forName(tgName).
-                    getConstructor(new Class[] {String.class});
-                threadGroup = (ThreadGroup)ctor.newInstance(new Object[] {"AWT-ThreadGroup"});
-            } catch (Exception e) {
-                System.err.println("Failed loading " + tgName + ": " + e);
-            }
-        }
-
         Runnable initEQ = new Runnable() {
             public void run () {
                 EventQueue eventQueue;
@@ -144,17 +124,7 @@
             }
         };
 
-        if (threadGroup != null) {
-            Thread eqInitThread = new Thread(threadGroup, initEQ, "EventQueue-Init");
-            eqInitThread.start();
-            try {
-                eqInitThread.join();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        } else {
-            initEQ.run();
-        }
+        initEQ.run();
     }
 
     public boolean useBufferPerWindow() {
--- a/jdk/src/share/classes/sun/dc/DuctusRenderingEngine.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/dc/DuctusRenderingEngine.java	Wed Jan 19 19:00:30 2011 -0800
@@ -635,6 +635,88 @@
         return r;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public AATileGenerator getAATileGenerator(double x, double y,
+                                              double dx1, double dy1,
+                                              double dx2, double dy2,
+                                              double lw1, double lw2,
+                                              Region clip,
+                                              int bbox[])
+    {
+        // REMIND: Deal with large coordinates!
+        double ldx1, ldy1, ldx2, ldy2;
+        boolean innerpgram = (lw1 > 0 && lw2 > 0);
+
+        if (innerpgram) {
+            ldx1 = dx1 * lw1;
+            ldy1 = dy1 * lw1;
+            ldx2 = dx2 * lw2;
+            ldy2 = dy2 * lw2;
+            x -= (ldx1 + ldx2) / 2.0;
+            y -= (ldy1 + ldy2) / 2.0;
+            dx1 += ldx1;
+            dy1 += ldy1;
+            dx2 += ldx2;
+            dy2 += ldy2;
+            if (lw1 > 1 && lw2 > 1) {
+                // Inner parallelogram was entirely consumed by stroke...
+                innerpgram = false;
+            }
+        } else {
+            ldx1 = ldy1 = ldx2 = ldy2 = 0;
+        }
+
+        Rasterizer r = getRasterizer();
+
+        r.setUsage(Rasterizer.EOFILL);
+
+        r.beginPath();
+        r.beginSubpath((float) x, (float) y);
+        r.appendLine((float) (x+dx1), (float) (y+dy1));
+        r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+        r.appendLine((float) (x+dx2), (float) (y+dy2));
+        r.closedSubpath();
+        if (innerpgram) {
+            x += ldx1 + ldx2;
+            y += ldy1 + ldy2;
+            dx1 -= 2.0 * ldx1;
+            dy1 -= 2.0 * ldy1;
+            dx2 -= 2.0 * ldx2;
+            dy2 -= 2.0 * ldy2;
+            r.beginSubpath((float) x, (float) y);
+            r.appendLine((float) (x+dx1), (float) (y+dy1));
+            r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+            r.appendLine((float) (x+dx2), (float) (y+dy2));
+            r.closedSubpath();
+        }
+
+        try {
+            r.endPath();
+            r.getAlphaBox(bbox);
+            clip.clipBoxToBounds(bbox);
+            if (bbox[0] >= bbox[2] || bbox[1] >= bbox[3]) {
+                dropRasterizer(r);
+                return null;
+            }
+            r.setOutputArea(bbox[0], bbox[1],
+                            bbox[2] - bbox[0],
+                            bbox[3] - bbox[1]);
+        } catch (PRException e) {
+            /*
+             * This exeption is thrown from the native part of the Ductus
+             * (only in case of a debug build) to indicate that some
+             * segments of the path have very large coordinates.
+             * See 4485298 for more info.
+             */
+            System.err.println("DuctusRenderingEngine.getAATileGenerator: "+e);
+        }
+
+        return r;
+    }
+
     private void feedConsumer(PathConsumer consumer, PathIterator pi) {
         try {
             consumer.beginPath();
--- a/jdk/src/share/classes/sun/font/FileFontStrike.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/font/FileFontStrike.java	Wed Jan 19 19:00:30 2011 -0800
@@ -58,10 +58,10 @@
     private static final int SEGINTARRAY   = 3;
     private static final int SEGLONGARRAY  = 4;
 
-    private int glyphCacheFormat = UNINITIALISED;
+    private volatile int glyphCacheFormat = UNINITIALISED;
 
-    /* segmented arrays are blocks of 256 */
-    private static final int SEGSHIFT = 8;
+    /* segmented arrays are blocks of 32 */
+    private static final int SEGSHIFT = 5;
     private static final int SEGSIZE  = 1 << SEGSHIFT;
 
     private boolean segmentedCache;
@@ -171,7 +171,7 @@
         mapper = fileFont.getMapper();
         int numGlyphs = mapper.getNumGlyphs();
 
-        /* Always segment for fonts with > 2K glyphs, but also for smaller
+        /* Always segment for fonts with > 256 glyphs, but also for smaller
          * fonts with non-typical sizes and transforms.
          * Segmenting for all non-typical pt sizes helps to minimise memory
          * usage when very many distinct strikes are created.
@@ -522,32 +522,33 @@
     }
 
     /* Called only from synchronized code or constructor */
-    private void initGlyphCache() {
+    private synchronized void initGlyphCache() {
 
         int numGlyphs = mapper.getNumGlyphs();
-
+        int tmpFormat = UNINITIALISED;
         if (segmentedCache) {
             int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE;
             if (longAddresses) {
-                glyphCacheFormat = SEGLONGARRAY;
+                tmpFormat = SEGLONGARRAY;
                 segLongGlyphImages = new long[numSegments][];
                 this.disposer.segLongGlyphImages = segLongGlyphImages;
              } else {
-                 glyphCacheFormat = SEGINTARRAY;
+                 tmpFormat = SEGINTARRAY;
                  segIntGlyphImages = new int[numSegments][];
                  this.disposer.segIntGlyphImages = segIntGlyphImages;
              }
         } else {
             if (longAddresses) {
-                glyphCacheFormat = LONGARRAY;
+                tmpFormat = LONGARRAY;
                 longGlyphImages = new long[numGlyphs];
                 this.disposer.longGlyphImages = longGlyphImages;
             } else {
-                glyphCacheFormat = INTARRAY;
+                tmpFormat = INTARRAY;
                 intGlyphImages = new int[numGlyphs];
                 this.disposer.intGlyphImages = intGlyphImages;
             }
         }
+        glyphCacheFormat = tmpFormat;
     }
 
     float getGlyphAdvance(int glyphCode) {
--- a/jdk/src/share/classes/sun/font/Font2D.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/font/Font2D.java	Wed Jan 19 19:00:30 2011 -0800
@@ -343,7 +343,21 @@
             }
             strike = createStrike(desc);
             //StrikeCache.addStrike();
-            strikeRef = StrikeCache.getStrikeRef(strike);
+            /* If we are creating many strikes on this font which
+             * involve non-quadrant rotations, or more general
+             * transforms which include shears, then force the use
+             * of weak references rather than soft references.
+             * This means that it won't live much beyond the next GC,
+             * which is what we want for what is likely a transient strike.
+             */
+            int txType = desc.glyphTx.getType();
+            if (txType == AffineTransform.TYPE_GENERAL_TRANSFORM ||
+                (txType & AffineTransform.TYPE_GENERAL_ROTATION) != 0 &&
+                strikeCache.size() > 10) {
+                strikeRef = StrikeCache.getStrikeRef(strike, true);
+            } else {
+                strikeRef = StrikeCache.getStrikeRef(strike);
+            }
             strikeCache.put(desc, strikeRef);
             //strike.lastlookupTime = System.currentTimeMillis();
             lastFontStrike = new SoftReference(strike);
--- a/jdk/src/share/classes/sun/java2d/SurfaceData.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/SurfaceData.java	Wed Jan 19 19:00:30 2011 -0800
@@ -367,16 +367,17 @@
     public static final TextPipe aaTextRenderer;
     public static final TextPipe lcdTextRenderer;
 
-    protected static final CompositePipe colorPipe;
+    protected static final AlphaColorPipe colorPipe;
     protected static final PixelToShapeConverter colorViaShape;
     protected static final PixelToParallelogramConverter colorViaPgram;
     protected static final TextPipe colorText;
     protected static final CompositePipe clipColorPipe;
     protected static final TextPipe clipColorText;
     protected static final AAShapePipe AAColorShape;
-    protected static final PixelToShapeConverter AAColorViaShape;
+    protected static final PixelToParallelogramConverter AAColorViaShape;
+    protected static final PixelToParallelogramConverter AAColorViaPgram;
     protected static final AAShapePipe AAClipColorShape;
-    protected static final PixelToShapeConverter AAClipColorViaShape;
+    protected static final PixelToParallelogramConverter AAClipColorViaShape;
 
     protected static final CompositePipe paintPipe;
     protected static final SpanShapeRenderer paintShape;
@@ -385,9 +386,9 @@
     protected static final CompositePipe clipPaintPipe;
     protected static final TextPipe clipPaintText;
     protected static final AAShapePipe AAPaintShape;
-    protected static final PixelToShapeConverter AAPaintViaShape;
+    protected static final PixelToParallelogramConverter AAPaintViaShape;
     protected static final AAShapePipe AAClipPaintShape;
-    protected static final PixelToShapeConverter AAClipPaintViaShape;
+    protected static final PixelToParallelogramConverter AAClipPaintViaShape;
 
     protected static final CompositePipe compPipe;
     protected static final SpanShapeRenderer compShape;
@@ -396,9 +397,9 @@
     protected static final CompositePipe clipCompPipe;
     protected static final TextPipe clipCompText;
     protected static final AAShapePipe AACompShape;
-    protected static final PixelToShapeConverter AACompViaShape;
+    protected static final PixelToParallelogramConverter AACompViaShape;
     protected static final AAShapePipe AAClipCompShape;
-    protected static final PixelToShapeConverter AAClipCompViaShape;
+    protected static final PixelToParallelogramConverter AAClipCompViaShape;
 
     protected static final DrawImagePipe imagepipe;
 
@@ -427,6 +428,22 @@
         }
     }
 
+    private static PixelToParallelogramConverter
+        makeConverter(AAShapePipe renderer,
+                      ParallelogramPipe pgrampipe)
+    {
+        return new PixelToParallelogramConverter(renderer,
+                                                 pgrampipe,
+                                                 1.0/8.0, 0.499,
+                                                 false);
+    }
+
+    private static PixelToParallelogramConverter
+        makeConverter(AAShapePipe renderer)
+    {
+        return makeConverter(renderer, renderer);
+    }
+
     static {
         colorPrimitives = new LoopPipe();
 
@@ -445,9 +462,10 @@
         clipColorPipe = new SpanClipRenderer(colorPipe);
         clipColorText = new TextRenderer(clipColorPipe);
         AAColorShape = new AAShapePipe(colorPipe);
-        AAColorViaShape = new PixelToShapeConverter(AAColorShape);
+        AAColorViaShape = makeConverter(AAColorShape);
+        AAColorViaPgram = makeConverter(AAColorShape, colorPipe);
         AAClipColorShape = new AAShapePipe(clipColorPipe);
-        AAClipColorViaShape = new PixelToShapeConverter(AAClipColorShape);
+        AAClipColorViaShape = makeConverter(AAClipColorShape);
 
         paintPipe = new AlphaPaintPipe();
         paintShape = new SpanShapeRenderer.Composite(paintPipe);
@@ -456,9 +474,9 @@
         clipPaintPipe = new SpanClipRenderer(paintPipe);
         clipPaintText = new TextRenderer(clipPaintPipe);
         AAPaintShape = new AAShapePipe(paintPipe);
-        AAPaintViaShape = new PixelToShapeConverter(AAPaintShape);
+        AAPaintViaShape = makeConverter(AAPaintShape);
         AAClipPaintShape = new AAShapePipe(clipPaintPipe);
-        AAClipPaintViaShape = new PixelToShapeConverter(AAClipPaintShape);
+        AAClipPaintViaShape = makeConverter(AAClipPaintShape);
 
         compPipe = new GeneralCompositePipe();
         compShape = new SpanShapeRenderer.Composite(compPipe);
@@ -467,9 +485,9 @@
         clipCompPipe = new SpanClipRenderer(compPipe);
         clipCompText = new TextRenderer(clipCompPipe);
         AACompShape = new AAShapePipe(compPipe);
-        AACompViaShape = new PixelToShapeConverter(AACompShape);
+        AACompViaShape = makeConverter(AACompShape);
         AAClipCompShape = new AAShapePipe(clipCompPipe);
-        AAClipCompViaShape = new PixelToShapeConverter(AAClipCompShape);
+        AAClipCompViaShape = makeConverter(AAClipCompShape);
 
         imagepipe = new DrawImage();
     }
@@ -591,12 +609,12 @@
                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
                     sg2d.drawpipe = AAClipCompViaShape;
                     sg2d.fillpipe = AAClipCompViaShape;
-                    sg2d.shapepipe = AAClipCompShape;
+                    sg2d.shapepipe = AAClipCompViaShape;
                     sg2d.textpipe = clipCompText;
                 } else {
                     sg2d.drawpipe = AACompViaShape;
                     sg2d.fillpipe = AACompViaShape;
-                    sg2d.shapepipe = AACompShape;
+                    sg2d.shapepipe = AACompViaShape;
                     sg2d.textpipe = compText;
                 }
             } else {
@@ -616,13 +634,17 @@
                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
                     sg2d.drawpipe = AAClipColorViaShape;
                     sg2d.fillpipe = AAClipColorViaShape;
-                    sg2d.shapepipe = AAClipColorShape;
+                    sg2d.shapepipe = AAClipColorViaShape;
                     sg2d.textpipe = clipColorText;
                 } else {
-                    sg2d.drawpipe = AAColorViaShape;
-                    sg2d.fillpipe = AAColorViaShape;
-                    sg2d.shapepipe = AAColorShape;
-                    if (sg2d.paintState > sg2d.PAINT_OPAQUECOLOR ||
+                    PixelToParallelogramConverter converter =
+                        (sg2d.alphafill.canDoParallelograms()
+                         ? AAColorViaPgram
+                         : AAColorViaShape);
+                    sg2d.drawpipe = converter;
+                    sg2d.fillpipe = converter;
+                    sg2d.shapepipe = converter;
+                    if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||
                         sg2d.compositeState > sg2d.COMP_ISCOPY)
                     {
                         sg2d.textpipe = colorText;
@@ -634,12 +656,12 @@
                 if (sg2d.clipState == sg2d.CLIP_SHAPE) {
                     sg2d.drawpipe = AAClipPaintViaShape;
                     sg2d.fillpipe = AAClipPaintViaShape;
-                    sg2d.shapepipe = AAClipPaintShape;
+                    sg2d.shapepipe = AAClipPaintViaShape;
                     sg2d.textpipe = clipPaintText;
                 } else {
                     sg2d.drawpipe = AAPaintViaShape;
                     sg2d.fillpipe = AAPaintViaShape;
-                    sg2d.shapepipe = AAPaintShape;
+                    sg2d.shapepipe = AAPaintViaShape;
                     sg2d.textpipe = paintText;
                 }
             }
@@ -793,6 +815,18 @@
         }
     }
 
+    private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {
+        CompositeType compType = sg2d.imageComp;
+        if (sg2d.compositeState == sg2d.COMP_ISCOPY) {
+            if (compType == CompositeType.SrcOverNoEa) {
+                compType = CompositeType.OpaqueSrcOverNoEa;
+            } else {
+                compType = CompositeType.SrcNoEa;
+            }
+        }
+        return compType;
+    }
+
     /**
      * Returns a MaskFill object that can be used on this destination
      * with the source (paint) and composite types determined by the given
@@ -802,9 +836,10 @@
      * surface) before returning a specific MaskFill object.
      */
     protected MaskFill getMaskFill(SunGraphics2D sg2d) {
-        return MaskFill.getFromCache(getPaintSurfaceType(sg2d),
-                                     sg2d.imageComp,
-                                     getSurfaceType());
+        SurfaceType src = getPaintSurfaceType(sg2d);
+        CompositeType comp = getFillCompositeType(sg2d);
+        SurfaceType dst = getSurfaceType();
+        return MaskFill.getFromCache(src, comp, dst);
     }
 
     private static RenderCache loopcache = new RenderCache(30);
@@ -816,9 +851,7 @@
      */
     public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
         SurfaceType src = getPaintSurfaceType(sg2d);
-        CompositeType comp = (sg2d.compositeState == sg2d.COMP_ISCOPY
-                              ? CompositeType.SrcNoEa
-                              : sg2d.imageComp);
+        CompositeType comp = getFillCompositeType(sg2d);
         SurfaceType dst = sg2d.getSurfaceData().getSurfaceType();
 
         Object o = loopcache.get(src, comp, dst);
--- a/jdk/src/share/classes/sun/java2d/loops/CompositeType.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/loops/CompositeType.java	Wed Jan 19 19:00:30 2011 -0800
@@ -27,6 +27,7 @@
 
 import java.awt.image.BufferedImage;
 import java.awt.AlphaComposite;
+import java.util.HashMap;
 
 /**
  * A CompositeType object provides a chained description of a type of
@@ -51,6 +52,11 @@
  * the indicated algorithm if all of the more specific searches fail.
  */
 public final class CompositeType {
+
+    private static int unusedUID = 1;
+    private static final HashMap<String,Integer> compositeUIDMap =
+        new HashMap<String,Integer>(100);
+
     /*
      * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING
      * ALGORITHMS THEY CAN PERFORM
@@ -153,6 +159,22 @@
         SrcOverNoEa   = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA);
 
     /*
+     * A special CompositeType for the case where we are filling in
+     * SrcOverNoEa mode with an opaque color.  In that case then the
+     * best loop for us to use would be a SrcNoEa loop, but what if
+     * there is no such loop?  In that case then we would end up
+     * backing off to a Src loop (which should still be fine) or an
+     * AnyAlpha loop which would be slower than a SrcOver loop in
+     * most cases.
+     * The fix is to use the following chain which looks for loops
+     * in the following order:
+     *    SrcNoEa, Src, SrcOverNoEa, SrcOver, AnyAlpha
+     */
+    public static final CompositeType
+        OpaqueSrcOverNoEa = SrcOverNoEa.deriveSubType(DESC_SRC)
+                                       .deriveSubType(DESC_SRC_NO_EA);
+
+    /*
      * END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS
      */
 
@@ -210,7 +232,6 @@
         }
     }
 
-    private static int unusedUID = 1;
     private int uniqueID;
     private String desc;
     private CompositeType next;
@@ -218,14 +239,20 @@
     private CompositeType(CompositeType parent, String desc) {
         next = parent;
         this.desc = desc;
-        this.uniqueID = makeUniqueID();
+        this.uniqueID = makeUniqueID(desc);
     }
 
-    private synchronized static final int makeUniqueID() {
-        if (unusedUID > 255) {
-            throw new InternalError("composite type id overflow");
+    public synchronized static final int makeUniqueID(String desc) {
+        Integer i = compositeUIDMap.get(desc);
+
+        if (i == null) {
+            if (unusedUID > 255) {
+                throw new InternalError("composite type id overflow");
+            }
+            i = unusedUID++;
+            compositeUIDMap.put(desc, i);
         }
-        return unusedUID++;
+        return i;
     }
 
     public int getUniqueID() {
--- a/jdk/src/share/classes/sun/java2d/loops/MaskFill.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/loops/MaskFill.java	Wed Jan 19 19:00:30 2011 -0800
@@ -50,6 +50,10 @@
 public class MaskFill extends GraphicsPrimitive
 {
     public static final String methodSignature = "MaskFill(...)".toString();
+    public static final String fillPgramSignature =
+        "FillAAPgram(...)".toString();
+    public static final String drawPgramSignature =
+        "DrawAAPgram(...)".toString();
 
     public static final int primTypeID = makePrimTypeID();
 
@@ -92,6 +96,14 @@
         return fill;
     }
 
+    protected MaskFill(String alternateSignature,
+                       SurfaceType srctype,
+                       CompositeType comptype,
+                       SurfaceType dsttype)
+    {
+        super(alternateSignature, primTypeID, srctype, comptype, dsttype);
+    }
+
     protected MaskFill(SurfaceType srctype,
                        CompositeType comptype,
                        SurfaceType dsttype)
@@ -115,6 +127,23 @@
                                 int x, int y, int w, int h,
                                 byte[] mask, int maskoff, int maskscan);
 
+    public native void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+                                   Composite comp,
+                                   double x, double y,
+                                   double dx1, double dy1,
+                                   double dx2, double dy2);
+
+    public native void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+                                   Composite comp,
+                                   double x, double y,
+                                   double dx1, double dy1,
+                                   double dx2, double dy2,
+                                   double lw1, double lw2);
+
+    public boolean canDoParallelograms() {
+        return (getNativePrim() != 0);
+    }
+
     static {
         GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null));
     }
@@ -182,12 +211,22 @@
 
     private static class TraceMaskFill extends MaskFill {
         MaskFill target;
+        MaskFill fillPgramTarget;
+        MaskFill drawPgramTarget;
 
         public TraceMaskFill(MaskFill target) {
             super(target.getSourceType(),
                   target.getCompositeType(),
                   target.getDestType());
             this.target = target;
+            this.fillPgramTarget = new MaskFill(fillPgramSignature,
+                                                target.getSourceType(),
+                                                target.getCompositeType(),
+                                                target.getDestType());
+            this.drawPgramTarget = new MaskFill(drawPgramSignature,
+                                                target.getSourceType(),
+                                                target.getCompositeType(),
+                                                target.getDestType());
         }
 
         public GraphicsPrimitive traceWrap() {
@@ -203,5 +242,32 @@
             target.MaskFill(sg2d, sData, comp, x, y, w, h,
                             mask, maskoff, maskscan);
         }
+
+        public void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+                                Composite comp,
+                                double x, double y,
+                                double dx1, double dy1,
+                                double dx2, double dy2)
+        {
+            tracePrimitive(fillPgramTarget);
+            target.FillAAPgram(sg2d, sData, comp,
+                               x, y, dx1, dy1, dx2, dy2);
+        }
+
+        public void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
+                                Composite comp,
+                                double x, double y,
+                                double dx1, double dy1,
+                                double dx2, double dy2,
+                                double lw1, double lw2)
+        {
+            tracePrimitive(drawPgramTarget);
+            target.DrawAAPgram(sg2d, sData, comp,
+                               x, y, dx1, dy1, dx2, dy2, lw1, lw2);
+        }
+
+        public boolean canDoParallelograms() {
+            return target.canDoParallelograms();
+        }
     }
 }
--- a/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java	Wed Jan 19 19:00:30 2011 -0800
@@ -28,6 +28,7 @@
 import java.awt.BasicStroke;
 import java.awt.Rectangle;
 import java.awt.Shape;
+import java.awt.geom.Rectangle2D;
 import java.awt.geom.PathIterator;
 import sun.awt.SunHints;
 import sun.java2d.SunGraphics2D;
@@ -39,7 +40,9 @@
  * This class sets up the Generator and computes the alpha tiles
  * and then passes them on to a CompositePipe object for painting.
  */
-public class AAShapePipe implements ShapeDrawPipe {
+public class AAShapePipe
+    implements ShapeDrawPipe, ParallelogramPipe
+{
     static RenderingEngine renderengine = RenderingEngine.getInstance();
 
     CompositePipe outpipe;
@@ -65,6 +68,59 @@
         renderPath(sg, s, null);
     }
 
+    private static Rectangle2D computeBBox(double x, double y,
+                                           double dx1, double dy1,
+                                           double dx2, double dy2)
+    {
+        double lox, loy, hix, hiy;
+        lox = hix = x;
+        loy = hiy = y;
+        if (dx1 < 0) { lox += dx1; } else { hix += dx1; }
+        if (dy1 < 0) { loy += dy1; } else { hiy += dy1; }
+        if (dx2 < 0) { lox += dx2; } else { hix += dx2; }
+        if (dy2 < 0) { loy += dy2; } else { hiy += dy2; }
+        return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy);
+    }
+
+    public void fillParallelogram(SunGraphics2D sg,
+                                  double x, double y,
+                                  double dx1, double dy1,
+                                  double dx2, double dy2)
+    {
+        Region clip = sg.getCompClip();
+        int abox[] = new int[4];
+        AATileGenerator aatg =
+            renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
+                                            clip, abox);
+        if (aatg == null) {
+            // Nothing to render
+            return;
+        }
+
+        renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
+    }
+
+    public void drawParallelogram(SunGraphics2D sg,
+                                  double x, double y,
+                                  double dx1, double dy1,
+                                  double dx2, double dy2,
+                                  double lw1, double lw2)
+    {
+        Region clip = sg.getCompClip();
+        int abox[] = new int[4];
+        AATileGenerator aatg =
+            renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
+                                            clip, abox);
+        if (aatg == null) {
+            // Nothing to render
+            return;
+        }
+
+        // Note that bbox is of the original shape, not the wide path.
+        // This is appropriate for handing to Paint methods...
+        renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
+    }
+
     private static byte[] theTile;
 
     public synchronized static byte[] getAlphaTile(int len) {
@@ -85,8 +141,6 @@
         boolean adjust = (bs != null &&
                           sg.strokeHint != SunHints.INTVAL_STROKE_PURE);
         boolean thin = (sg.strokeState <= sg.STROKE_THINDASHED);
-        Object context = null;
-        byte alpha[] = null;
 
         Region clip = sg.getCompClip();
         int abox[] = new int[4];
@@ -98,6 +152,14 @@
             return;
         }
 
+        renderTiles(sg, s, aatg, abox);
+    }
+
+    public void renderTiles(SunGraphics2D sg, Shape s,
+                            AATileGenerator aatg, int abox[])
+    {
+        Object context = null;
+        byte alpha[] = null;
         try {
             context = outpipe.startSequence(sg, s,
                                             new Rectangle(abox[0], abox[1],
--- a/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java	Wed Jan 19 19:00:30 2011 -0800
@@ -34,7 +34,7 @@
  * into a destination that supports direct alpha compositing of a solid
  * color, according to one of the rules in the AlphaComposite class.
  */
-public class AlphaColorPipe implements CompositePipe {
+public class AlphaColorPipe implements CompositePipe, ParallelogramPipe {
     public AlphaColorPipe() {
     }
 
@@ -64,4 +64,23 @@
     public void endSequence(Object context) {
         return;
     }
+
+    public void fillParallelogram(SunGraphics2D sg,
+                                  double x, double y,
+                                  double dx1, double dy1,
+                                  double dx2, double dy2)
+    {
+        sg.alphafill.FillAAPgram(sg, sg.getSurfaceData(), sg.composite,
+                                 x, y, dx1, dy1, dx2, dy2);
+    }
+
+    public void drawParallelogram(SunGraphics2D sg,
+                                  double x, double y,
+                                  double dx1, double dy1,
+                                  double dx2, double dy2,
+                                  double lw1, double lw2)
+    {
+        sg.alphafill.DrawAAPgram(sg, sg.getSurfaceData(), sg.composite,
+                                 x, y, dx1, dy1, dx2, dy2, lw1, lw2);
+    }
 }
--- a/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pipe/RenderingEngine.java	Wed Jan 19 19:00:30 2011 -0800
@@ -281,6 +281,72 @@
                                                        int bbox[]);
 
     /**
+     * Construct an antialiased tile generator for the given parallelogram
+     * store the bounds of the tile iteration in the bbox parameter.
+     * The parallelogram is specified as a starting point and 2 delta
+     * vectors that indicate the slopes of the 2 pairs of sides of the
+     * parallelogram.
+     * The 4 corners of the parallelogram are defined by the 4 points:
+     * <ul>
+     * <li> {@code x}, {@code y}
+     * <li> {@code x+dx1}, {@code y+dy1}
+     * <li> {@code x+dx1+dx2}, {@code y+dy1+dy2}
+     * <li> {@code x+dx2}, {@code y+dy2}
+     * </ul>
+     * The {@code lw1} and {@code lw2} parameters provide a specification
+     * for an optionally stroked parallelogram if they are positive numbers.
+     * The {@code lw1} parameter is the ratio of the length of the {@code dx1},
+     * {@code dx2} delta vector to half of the line width in that same
+     * direction.
+     * The {@code lw2} parameter provides the same ratio for the other delta
+     * vector.
+     * If {@code lw1} and {@code lw2} are both greater than zero, then
+     * the parallelogram figure is doubled by both expanding and contracting
+     * each delta vector by its corresponding {@code lw} value.
+     * If either (@code lw1) or {@code lw2} are also greater than 1, then
+     * the inner (contracted) parallelogram disappears and the figure is
+     * simply a single expanded parallelogram.
+     * The {@code clip} parameter specifies the current clip in effect
+     * in device coordinates and can be used to prune the data for the
+     * operation, but the renderer is not required to perform any
+     * clipping.
+     * <p>
+     * Upon returning, this method will fill the {@code bbox} parameter
+     * with 4 values indicating the bounds of the iteration of the
+     * tile generator.
+     * The iteration order of the tiles will be as specified by the
+     * pseudo-code:
+     * <pre>
+     *     for (y = bbox[1]; y < bbox[3]; y += tileheight) {
+     *         for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
+     *         }
+     *     }
+     * </pre>
+     * If there is no output to be rendered, this method may return
+     * null.
+     *
+     * @param x the X coordinate of the first corner of the parallelogram
+     * @param y the Y coordinate of the first corner of the parallelogram
+     * @param dx1 the X coordinate delta of the first leg of the parallelogram
+     * @param dy1 the Y coordinate delta of the first leg of the parallelogram
+     * @param dx2 the X coordinate delta of the second leg of the parallelogram
+     * @param dy2 the Y coordinate delta of the second leg of the parallelogram
+     * @param lw1 the line width ratio for the first leg of the parallelogram
+     * @param lw2 the line width ratio for the second leg of the parallelogram
+     * @param clip the current clip in effect in device coordinates
+     * @param bbox returns the bounds of the iteration
+     * @return the {@code AATileGenerator} instance to be consulted
+     *         for tile coverages, or null if there is no output to render
+     * @since 1.7
+     */
+    public abstract AATileGenerator getAATileGenerator(double x, double y,
+                                                       double dx1, double dy1,
+                                                       double dx2, double dy2,
+                                                       double lw1, double lw2,
+                                                       Region clip,
+                                                       int bbox[]);
+
+    /**
      * Returns the minimum pen width that the antialiasing rasterizer
      * can represent without dropouts occuring.
      * @since 1.7
@@ -393,5 +459,24 @@
                                              bs, thin, normalize,
                                              bbox);
         }
+        public AATileGenerator getAATileGenerator(double x, double y,
+                                                  double dx1, double dy1,
+                                                  double dx2, double dy2,
+                                                  double lw1, double lw2,
+                                                  Region clip,
+                                                  int bbox[])
+        {
+            System.out.println(name+".getAATileGenerator("+
+                               x+", "+y+", "+
+                               dx1+", "+dy1+", "+
+                               dx2+", "+dy2+", "+
+                               lw1+", "+lw2+", "+
+                               clip+")");
+            return target.getAATileGenerator(x, y,
+                                             dx1, dy1,
+                                             dx2, dy2,
+                                             lw1, lw2,
+                                             clip, bbox);
+        }
     }
 }
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Wed Jan 19 19:00:30 2011 -0800
@@ -557,6 +557,69 @@
         return ptg;
     }
 
+    public AATileGenerator getAATileGenerator(double x, double y,
+                                              double dx1, double dy1,
+                                              double dx2, double dy2,
+                                              double lw1, double lw2,
+                                              Region clip,
+                                              int bbox[])
+    {
+        // REMIND: Deal with large coordinates!
+        double ldx1, ldy1, ldx2, ldy2;
+        boolean innerpgram = (lw1 > 0 && lw2 > 0);
+
+        if (innerpgram) {
+            ldx1 = dx1 * lw1;
+            ldy1 = dy1 * lw1;
+            ldx2 = dx2 * lw2;
+            ldy2 = dy2 * lw2;
+            x -= (ldx1 + ldx2) / 2.0;
+            y -= (ldy1 + ldy2) / 2.0;
+            dx1 += ldx1;
+            dy1 += ldy1;
+            dx2 += ldx2;
+            dy2 += ldy2;
+            if (lw1 > 1 && lw2 > 1) {
+                // Inner parallelogram was entirely consumed by stroke...
+                innerpgram = false;
+            }
+        } else {
+            ldx1 = ldy1 = ldx2 = ldy2 = 0;
+        }
+
+        Renderer r = new Renderer(3, 3,
+                                  clip.getLoX(), clip.getLoY(),
+                                  clip.getWidth(), clip.getHeight(),
+                                  PathIterator.WIND_EVEN_ODD);
+
+        r.moveTo((float) x, (float) y);
+        r.lineTo((float) (x+dx1), (float) (y+dy1));
+        r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+        r.lineTo((float) (x+dx2), (float) (y+dy2));
+        r.closePath();
+
+        if (innerpgram) {
+            x += ldx1 + ldx2;
+            y += ldy1 + ldy2;
+            dx1 -= 2.0 * ldx1;
+            dy1 -= 2.0 * ldy1;
+            dx2 -= 2.0 * ldx2;
+            dy2 -= 2.0 * ldy2;
+            r.moveTo((float) x, (float) y);
+            r.lineTo((float) (x+dx1), (float) (y+dy1));
+            r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2));
+            r.lineTo((float) (x+dx2), (float) (y+dy2));
+            r.closePath();
+        }
+
+        r.pathDone();
+
+        r.endRendering();
+        PiscesTileGenerator ptg = new PiscesTileGenerator(r, r.MAX_AA_ALPHA);
+        ptg.getBbox(bbox);
+        return ptg;
+    }
+
     /**
      * Returns the minimum pen width that the antialiasing rasterizer
      * can represent without dropouts occuring.
--- a/jdk/src/share/native/sun/awt/image/awt_parseImage.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/awt/image/awt_parseImage.c	Wed Jan 19 19:00:30 2011 -0800
@@ -178,7 +178,7 @@
         jnbits = (*env)->GetObjectField(env, rasterP->jsampleModel,
                                         g_SPPSMnBitsID);
         if (jmask == NULL || joffs == NULL || jnbits == NULL ||
-            rasterP->sppsm.maxBitSize < 0 || rasterP->sppsm.maxBitSize > 8)
+            rasterP->sppsm.maxBitSize < 0)
         {
             JNU_ThrowInternalError(env, "Can't grab SPPSM fields");
             return -1;
@@ -280,6 +280,17 @@
                                   rasterP->chanOffsets);
     }
 
+    /* additioanl check for sppsm fields validity: make sure that
+     * size of raster samples doesn't exceed the data type cpacity.
+     */
+    if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */
+        rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
+        rasterP->sppsm.maxBitSize > (rasterP->dataSize * 8))
+    {
+        JNU_ThrowInternalError(env, "Raster samples are too big");
+        return -1;
+    }
+
 #if 0
     fprintf(stderr,"---------------------\n");
     fprintf(stderr,"Width  : %d\n",rasterP->width);
--- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h	Wed Jan 19 19:00:30 2011 -0800
@@ -88,27 +88,18 @@
 /*      blend (lerp between) two rgb quads
         src and dst alpha is ignored
         the algorithm: src*alpha+dst*(1-alpha)=(src-dst)*alpha+dst, rb and g are done separately
-        it's possible to verify that it's almost accurate indeed */
-
+*/
 INLINE rgbquad_t
 blendRGB(rgbquad_t dst, rgbquad_t src, rgbquad_t alpha)
 {
-    const rgbquad_t dstrb = dst & 0xFF00FF;
-    const rgbquad_t dstg = dst & 0xFF00;
-    const rgbquad_t srcrb = src & 0xFF00FF;
-    const rgbquad_t srcg = src & 0xFF00;
-
-    rgbquad_t drb = srcrb - dstrb;
-    rgbquad_t dg = srcg - dstg;
+    const rgbquad_t a = alpha;
+    const rgbquad_t a1 = 0xFF - alpha;
 
-    alpha += 1;
-
-    drb *= alpha;
-    dg *= alpha;
-    drb >>= 8;
-    dg >>= 8;
-
-    return ((drb + dstrb) & 0xFF00FF) | ((dg + dstg) & 0xFF00);
+    return MAKE_QUAD(
+        (rgbquad_t)((QUAD_RED(src) * a + QUAD_RED(dst) * a1) / 0xFF),
+        (rgbquad_t)((QUAD_GREEN(src) * a + QUAD_GREEN(dst) * a1) / 0xFF),
+        (rgbquad_t)((QUAD_BLUE(src) * a + QUAD_BLUE(dst) * a1) / 0xFF),
+        0);
 }
 
 /*      scales rgb quad by alpha. basically similar to what's above. src alpha is retained.
--- a/jdk/src/share/native/sun/java2d/loops/DrawParallelogram.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/loops/DrawParallelogram.c	Wed Jan 19 19:00:30 2011 -0800
@@ -26,14 +26,11 @@
 #include "math.h"
 #include "GraphicsPrimitiveMgr.h"
 #include "LineUtils.h"
-#include "LoopMacros.h"
 #include "Trace.h"
+#include "ParallelogramUtils.h"
 
-#include "sun_java2d_loops_FillParallelogram.h"
 #include "sun_java2d_loops_DrawParallelogram.h"
 
-DECLARE_SOLID_DRAWLINE(AnyInt);
-
 #define HANDLE_PGRAM_EDGE(X1, Y1, X2, Y2, \
                           pRasInfo, pixel, pPrim, pFunc, pCompInfo) \
     do { \
@@ -46,28 +43,6 @@
                                ix1, iy1, ix2, iy2, JNI_TRUE); \
     } while (0)
 
-#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
-    do { \
-        double vmin, vmax; \
-        if (dv1 < 0) { \
-            vmin = v0+dv1; \
-            vmax = v0; \
-        } else { \
-            vmin = v0; \
-            vmax = v0+dv1; \
-        } \
-        if (dv2 < 0) { \
-            vmin -= dv2; \
-        } else { \
-            vmax += dv2; \
-        } \
-        bmin = (jint) floor(vmin + 0.5); \
-        bmax = (jint) floor(vmax + 0.5); \
-    } while(0)
-
-#define PGRAM_INIT_X(starty, x, y, slope) \
-    (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
-
 typedef struct {
     jdouble x0;
     jdouble y0;
@@ -136,20 +111,8 @@
      * Sort parallelogram by y values, ensure that each delta vector
      * has a non-negative y delta.
      */
-    if (dy1 < 0) {
-        x0 += dx1;  y0 += dy1;
-        dx1 = -dx1; dy1 = -dy1;
-    }
-    if (dy2 < 0) {
-        x0 += dx2;  y0 += dy2;
-        dx2 = -dx2; dy2 = -dy2;
-    }
-    /* Sort delta vectors so dxy1 is left of dxy2. */
-    if (dx1 * dy2 > dx2 * dy1) {
-        double v = dx1; dx1 = dx2; dx2 = v;
-               v = dy1; dy1 = dy2; dy2 = v;
-               v = lw1; lw1 = lw2; lw2 = v;
-    }
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
+               v = lw1; lw1 = lw2; lw2 = v;);
 
     // dx,dy for line width in the "1" and "2" directions.
     ldx1 = dx1 * lw1;
@@ -161,7 +124,7 @@
     ox0 = x0 - (ldx1 + ldx2) / 2.0;
     oy0 = y0 - (ldy1 + ldy2) / 2.0;
 
-    PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2);
+    PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_FALSE);
     iy1 = (jint) floor(oy0 + 0.5);
     iy2 = (jint) floor(oy0 + dy1 + ldy1 + dy2 + ldy2 + 0.5);
 
@@ -212,7 +175,7 @@
             // Only need to generate 4 quads if the interior still
             // has a hole in it (i.e. if the line width ratios were
             // both less than 1.0)
-            if (lw1 < 1.0f && lw2 < 1.0f) {
+            if (lw1 < 1.0 && lw2 < 1.0) {
                 // If the line widths are both less than a pixel wide
                 // then we can use a drawline function instead for even
                 // more performance.
--- a/jdk/src/share/native/sun/java2d/loops/FillParallelogram.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/loops/FillParallelogram.c	Wed Jan 19 19:00:30 2011 -0800
@@ -25,31 +25,10 @@
 
 #include "math.h"
 #include "GraphicsPrimitiveMgr.h"
+#include "ParallelogramUtils.h"
 
 #include "sun_java2d_loops_FillParallelogram.h"
 
-#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
-    do { \
-        double vmin, vmax; \
-        if (dv1 < 0) { \
-            vmin = v0+dv1; \
-            vmax = v0; \
-        } else { \
-            vmin = v0; \
-            vmax = v0+dv1; \
-        } \
-        if (dv2 < 0) { \
-            vmin -= dv2; \
-        } else { \
-            vmax += dv2; \
-        } \
-        bmin = (jint) floor(vmin + 0.5); \
-        bmax = (jint) floor(vmax + 0.5); \
-    } while(0)
-
-#define PGRAM_INIT_X(starty, x, y, slope) \
-    (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
-
 /*
  * Class:     sun_java2d_loops_FillParallelogram
  * Method:    FillParallelogram
@@ -76,22 +55,11 @@
 
     /*
      * Sort parallelogram by y values, ensure that each delta vector
-     * has a non-negative y delta, and eliminate degenerate parallelograms.
+     * has a non-negative y delta.
      */
-    if (dy1 < 0) {
-        x0 += dx1;  y0 += dy1;
-        dx1 = -dx1; dy1 = -dy1;
-    }
-    if (dy2 < 0) {
-        x0 += dx2;  y0 += dy2;
-        dx2 = -dx2; dy2 = -dy2;
-    }
-    /* Sort delta vectors so dxy1 is left of dxy2. */
-    if (dx1 * dy2 > dx2 * dy1) {
-        double v = dx1; dx1 = dx2; dx2 = v;
-               v = dy1; dy1 = dy2; dy2 = v;
-    }
-    PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2);
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
+
+    PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_FALSE);
     iy1 = (jint) floor(y0 + 0.5);
     iy2 = (jint) floor(y0 + dy1 + dy2 + 0.5);
 
--- a/jdk/src/share/native/sun/java2d/loops/MaskFill.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/loops/MaskFill.c	Wed Jan 19 19:00:30 2011 -0800
@@ -23,7 +23,11 @@
  * questions.
  */
 
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
 #include "GraphicsPrimitiveMgr.h"
+#include "ParallelogramUtils.h"
 
 #include "sun_java2d_loops_MaskFill.h"
 
@@ -93,6 +97,967 @@
             }
         }
         SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+   }
+   SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
+}
+
+#define MASK_BUF_LEN 1024
+
+#define DblToMask(v) ((unsigned char) ((v)*255.9999))
+
+/* Fills an aligned rectangle with potentially translucent edges. */
+static void
+fillAARect(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+           CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+           void *pDst,
+           jdouble x1, jdouble y1, jdouble x2, jdouble y2)
+{
+    jint cx1 = pRasInfo->bounds.x1;
+    jint cy1 = pRasInfo->bounds.y1;
+    jint cx2 = pRasInfo->bounds.x2;
+    jint cy2 = pRasInfo->bounds.y2;
+    jint rx1 = (jint) ceil(x1);
+    jint ry1 = (jint) ceil(y1);
+    jint rx2 = (jint) floor(x2);
+    jint ry2 = (jint) floor(y2);
+    jint width = cx2 - cx1;
+    jint scan = pRasInfo->scanStride;
+    /* Convert xy12 into the edge coverage fractions for those edges. */
+    x1 = rx1-x1;
+    y1 = ry1-y1;
+    x2 = x2-rx2;
+    y2 = y2-ry2;
+    if (ry2 < ry1) {
+        /* Accumulate bottom coverage into top coverage. */
+        y1 = y1 + y2 - 1.0;
+        /* prevent processing of "bottom fractional row" */
+        ry2 = cy2;
+    }
+    if (rx2 < rx1) {
+        /* Accumulate right coverage into left coverage. */
+        x1 = x1 + x2 - 1.0;
+        /* prevent processing of "right fractional column" */
+        rx2 = cx2;
+    }
+    /* Check for a visible "top fractional row" and process it */
+    if (cy1 < ry1) {
+        unsigned char midcov = DblToMask(y1);
+        jint x;
+        for (x = 0; x < width; x++) {
+            pMask[x] = midcov;
+        }
+        if (cx1 < rx1) {
+            pMask[0] = DblToMask(y1 * x1);
+        }
+        if (cx2 > rx2) {
+            pMask[width-1] = DblToMask(y1 * x2);
+        }
+        (*pPrim->funcs.maskfill)(pDst,
+                                 pMask, 0, 0,
+                                 width, 1,
+                                 color, pRasInfo,
+                                 pPrim, pCompInfo);
+        pDst = PtrAddBytes(pDst, scan);
+        cy1++;
+    }
+    /* Check for a visible "left fract, solid middle, right fract" section. */
+    if (cy1 < ry2 && cy1 < cy2) {
+        jint midh = ((ry2 < cy2) ? ry2 : cy2) - cy1;
+        jint midx = cx1;
+        void *pMid = pDst;
+        /* First process the left "fractional column" if it is visible. */
+        if (midx < rx1) {
+            pMask[0] = DblToMask(x1);
+            /* Note: maskscan == 0 means we reuse this value for every row. */
+            (*pPrim->funcs.maskfill)(pMid,
+                                     pMask, 0, 0,
+                                     1, midh,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+            pMid = PtrAddBytes(pMid, pRasInfo->pixelStride);
+            midx++;
+        }
+        /* Process the central solid section if it is visible. */
+        if (midx < rx2 && midx < cx2) {
+            jint midw = ((rx2 < cx2) ? rx2 : cx2) - midx;
+            /* A NULL mask buffer means "all coverages are 0xff" */
+            (*pPrim->funcs.maskfill)(pMid,
+                                     NULL, 0, 0,
+                                     midw, midh,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+            pMid = PtrCoord(pMid, midw, pRasInfo->pixelStride, 0, 0);
+            midx += midw;
+        }
+        /* Finally process the right "fractional column" if it is visible. */
+        if (midx < cx2) {
+            pMask[0] = DblToMask(x2);
+            /* Note: maskscan == 0 means we reuse this value for every row. */
+            (*pPrim->funcs.maskfill)(pMid,
+                                     pMask, 0, 0,
+                                     1, midh,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        cy1 += midh;
+        pDst = PtrCoord(pDst, 0, 0, midh, scan);
+    }
+    /* Check for a visible "bottom fractional row" and process it */
+    if (cy1 < cy2) {
+        unsigned char midcov = DblToMask(y2);
+        jint x;
+        for (x = 0; x < width; x++) {
+            pMask[x] = midcov;
+        }
+        if (cx1 < rx1) {
+            pMask[0] = DblToMask(y2 * x1);
+        }
+        if (cx2 > rx2) {
+            pMask[width-1] = DblToMask(y2 * x2);
+        }
+        (*pPrim->funcs.maskfill)(pDst,
+                                 pMask, 0, 0,
+                                 width, 1,
+                                 color, pRasInfo,
+                                 pPrim, pCompInfo);
+    }
+}
+
+/*
+ * Support code for arbitrary tracing and MaskFill filling of
+ * non-rectilinear (diagonal) parallelograms.
+ *
+ * This code is based upon the following model of AA coverage.
+ *
+ * Each edge of a parallelogram (for fillPgram) or a double
+ * parallelogram (inner and outer parallelograms for drawPgram)
+ * can be rasterized independently because the geometry is well
+ * defined in such a way that none of the sides will ever cross
+ * each other and they have a fixed ordering that is fairly
+ * well predetermined.
+ *
+ * So, for each edge we will look at the diagonal line that
+ * the edge makes as it passes through a row of pixels.  Some
+ * such diagonal lines may pass entirely through the row of
+ * pixels in a single pixel column.  Some may cut across the
+ * row and pass through several pixel columns before they pass
+ * on to the next row.
+ *
+ * As the edge passes through the row of pixels it will affect
+ * the coverage of the pixels it passes through as well as all
+ * of the pixels to the right of the edge.  The coverage will
+ * either be increased (by a left edge of a parallelogram) or
+ * decreased (by a right edge) for all pixels to the right, until
+ * another edge passing the opposite direction is encountered.
+ *
+ * The coverage added or subtracted by an edge as it crosses a
+ * given pixel is calculated using a trapezoid formula in the
+ * following manner:
+ *
+ *                /
+ *     +-----+---/-+-----+
+ *     |     |  /  |     |
+ *     |     | /   |     |
+ *     +-----+/----+-----+
+ *           /
+ *
+ * The area to the right of that edge for the pixel where it
+ * crosses is given as:
+ *
+ *     trapheight * (topedge + bottomedge)/2
+ *
+ * Another thing to note is that the above formula gives the
+ * contribution of that edge to the given pixel where it crossed,
+ * but in so crossing the pixel row, it also created 100% coverage
+ * for all of the pixels to the right.
+ *
+ * This example was simplified in that the edge depicted crossed
+ * the complete pixel row and it did so entirely within the bounds
+ * of a single pixel column.  In practice, many edges may start or
+ * end in a given row and thus provide only partial row coverage
+ * (i.e. the total "trapheight" in the formula never reaches 1.0).
+ * And in other cases, edges may travel sideways through several
+ * pixel columns on a given pixel row from where they enter it to
+ * where the leave it (which also mans that the trapheight for a
+ * given pixel will be less than 1.0, but by the time the edge
+ * completes its journey through the pixel row the "coverage shadow"
+ * that it casts on all pixels to the right eventually reaches 100%).
+ *
+ * In order to simplify the calculations so that we don't have to
+ * keep propagating coverages we calculate for one edge "until we
+ * reach another edge" we will process one edge at a time and
+ * simply record in a buffer the amount that an edge added to
+ * or subtracted from the coverage for a given pixel and its
+ * following right-side neighbors.  Thus, the true total coverage
+ * of a given pixel is only determined by summing the deltas for
+ * that pixel and all of the pixels to its left.  Since we already
+ * have to scan the buffer to change floating point coverages into
+ * mask values for a MaskFill loop, it is simple enough to sum the
+ * values as we perform that scan from left to right.
+ *
+ * In the above example, note that 2 deltas need to be recorded even
+ * though the edge only intersected a single pixel.  The delta recorded
+ * for the pixel where the edge crossed will be approximately 55%
+ * (guesstimating by examining the poor ascii art) which is fine for
+ * determining how to render that pixel, but the rest of the pixels
+ * to its right should have their coverage modified by a full 100%
+ * and the 55% delta value we recorded for the pixel that the edge
+ * crossed will not get them there.  We adjust for this by adding
+ * the "remainder" of the coverage implied by the shadow to the
+ * pixel immediately to the right of where we record a trapezoidal
+ * contribution.  In this case a delta of 45% will be recorded in
+ * the pixel immediately to the right to raise the total to 100%.
+ *
+ * As we sum these delta values as we process the line from left
+ * to right, these delta values will typically drive the sum from
+ * 0% up to 100% and back down to 0% over the course of a single
+ * pixel row.  In the case of a drawn (double) parallelogram the
+ * sum will go to 100% and back to 0% twice on most scanlines.
+ *
+ * The fillAAPgram and drawAAPgram functions drive the main flow
+ * of the algorithm with help from the following structures,
+ * macros, and functions.  It is probably best to start with
+ * those 2 functions to gain an understanding of the algorithm.
+ */
+typedef struct {
+    jdouble x;
+    jdouble y;
+    jdouble xbot;
+    jdouble ybot;
+    jdouble xnexty;
+    jdouble ynextx;
+    jdouble xnextx;
+    jdouble linedx;
+    jdouble celldx;
+    jdouble celldy;
+    jboolean isTrailing;
+} EdgeInfo;
+
+#define MIN_DELTA  (1.0/256.0)
+
+/*
+ * Calculates slopes and deltas for an edge and stores results in an EdgeInfo.
+ * Returns true if the edge was valid (i.e. not ignored for some reason).
+ */
+static jboolean
+storeEdge(EdgeInfo *pEdge,
+          jdouble x, jdouble y, jdouble dx, jdouble dy,
+          jint cx1, jint cy1, jint cx2, jint cy2,
+          jboolean isTrailing)
+{
+    jdouble xbot = x + dx;
+    jdouble ybot = y + dy;
+    jboolean ret;
+
+    pEdge->x = x;
+    pEdge->y = y;
+    pEdge->xbot = xbot;
+    pEdge->ybot = ybot;
+
+    /* Note that parallelograms are sorted so dy is always non-negative */
+    if (dy > MIN_DELTA &&        /* NaN and horizontal protection */
+        ybot > cy1 &&            /* NaN and "OUT_ABOVE" protection */
+        y < cy2 &&               /* NaN and "OUT_BELOW" protection */
+        xbot == xbot &&          /* NaN protection */
+        (x < cx2 || xbot < cx2)) /* "OUT_RIGHT" protection */
+        /* Note: "OUT_LEFT" segments may still contribute coverage... */
+    {
+        /* no NaNs, dy is not horizontal, and segment contributes to clip */
+        if (dx < -MIN_DELTA || dx > MIN_DELTA) {
+            /* dx is not vertical */
+            jdouble linedx;
+            jdouble celldy;
+            jdouble nextx;
+
+            linedx = dx / dy;
+            celldy = dy / dx;
+            if (y < cy1) {
+                pEdge->x = x = x + (cy1 - y) * linedx;
+                pEdge->y = y = cy1;
+            }
+            pEdge->linedx = linedx;
+            if (dx < 0) {
+                pEdge->celldx = -1.0;
+                pEdge->celldy = -celldy;
+                pEdge->xnextx = nextx = ceil(x) - 1.0;
+            } else {
+                pEdge->celldx = +1.0;
+                pEdge->celldy = celldy;
+                pEdge->xnextx = nextx = floor(x) + 1.0;
+            }
+            pEdge->ynextx = y + (nextx - x) * celldy;
+            pEdge->xnexty = x + ((floor(y) + 1) - y) * linedx;
+        } else {
+            /* dx is essentially vertical */
+            if (y < cy1) {
+                pEdge->y = y = cy1;
+            }
+            pEdge->xbot = x;
+            pEdge->linedx = 0.0;
+            pEdge->celldx = 0.0;
+            pEdge->celldy = 1.0;
+            pEdge->xnextx = x;
+            pEdge->xnexty = x;
+            pEdge->ynextx = ybot;
+        }
+        ret = JNI_TRUE;
+    } else {
+        /* There is some reason to ignore this segment, "celldy=0" omits it */
+        pEdge->ybot = y;
+        pEdge->linedx = dx;
+        pEdge->celldx = dx;
+        pEdge->celldy = 0.0;
+        pEdge->xnextx = xbot;
+        pEdge->xnexty = xbot;
+        pEdge->ynextx = y;
+        ret = JNI_FALSE;
+    }
+    pEdge->isTrailing = isTrailing;
+    return ret;
+}
+
+/*
+ * Calculates and stores slopes and deltas for all edges of a parallelogram.
+ * Returns true if at least 1 edge was valid (i.e. not ignored for some reason).
+ *
+ * The inverted flag is true for an outer parallelogram (left and right
+ * edges are leading and trailing) and false for an inner parallelogram
+ * (where the left edge is trailing and the right edge is leading).
+ */
+static jboolean
+storePgram(EdgeInfo *pLeftEdge, EdgeInfo *pRightEdge,
+           jdouble x, jdouble y,
+           jdouble dx1, jdouble dy1,
+           jdouble dx2, jdouble dy2,
+           jint cx1, jint cy1, jint cx2, jint cy2,
+           jboolean inverted)
+{
+    jboolean ret = JNI_FALSE;
+    ret = (storeEdge(pLeftEdge  + 0,
+                     x    , y    , dx1, dy1,
+                     cx1, cy1, cx2, cy2, inverted) || ret);
+    ret = (storeEdge(pLeftEdge  + 1,
+                     x+dx1, y+dy1, dx2, dy2,
+                     cx1, cy1, cx2, cy2, inverted) || ret);
+    ret = (storeEdge(pRightEdge + 0,
+                     x    , y    , dx2, dy2,
+                     cx1, cy1, cx2, cy2, !inverted) || ret);
+    ret = (storeEdge(pRightEdge + 1,
+                     x+dx2, y+dy2, dx1, dy1,
+                     cx1, cy1, cx2, cy2, !inverted) || ret);
+    return ret;
+}
+
+/*
+ * The X0,Y0,X1,Y1 values represent a trapezoidal fragment whose
+ * coverage must be accounted for in the accum buffer.
+ *
+ * All four values are assumed to fall within (or on the edge of)
+ * a single pixel.
+ *
+ * The trapezoid area is accumulated into the proper element of
+ * the accum buffer and the remainder of the "slice height" is
+ * accumulated into the element to its right.
+ */
+#define INSERT_ACCUM(pACCUM, IMIN, IMAX, X0, Y0, X1, Y1, CX1, CX2, MULT) \
+    do { \
+        jdouble xmid = ((X0) + (X1)) * 0.5; \
+        if (xmid <= (CX2)) { \
+            jdouble sliceh = ((Y1) - (Y0)); \
+            jdouble slicearea; \
+            jint i; \
+            if (xmid < (CX1)) { \
+                /* Accumulate the entire slice height into accum[0]. */ \
+                i = 0; \
+                slicearea = sliceh; \
+            } else { \
+                jdouble xpos = floor(xmid); \
+                i = ((jint) xpos) - (CX1); \
+                slicearea = (xpos+1-xmid) * sliceh; \
+            } \
+            if (IMIN > i) { \
+                IMIN = i; \
+            } \
+            (pACCUM)[i++] += (jfloat) ((MULT) * slicearea); \
+            (pACCUM)[i++] += (jfloat) ((MULT) * (sliceh - slicearea)); \
+            if (IMAX < i) { \
+                IMAX = i; \
+            } \
+        } \
+    } while (0)
+
+/*
+ * Accumulate the contributions for a given edge crossing a given
+ * scan line into the corresponding entries of the accum buffer.
+ * CY1 is the Y coordinate of the top edge of the scanline and CY2
+ * is equal to (CY1 + 1) and is the Y coordinate of the bottom edge
+ * of the scanline.  CX1 and CX2 are the left and right edges of the
+ * clip (or area of interest) being rendered.
+ *
+ * The edge is processed from the top edge to the bottom edge and
+ * a single pixel column at a time.
+ */
+#define ACCUM_EDGE(pEDGE, pACCUM, IMIN, IMAX, CX1, CY1, CX2, CY2) \
+    do { \
+        jdouble x, y, xnext, ynext, xlast, ylast, dx, dy, mult; \
+        y = (pEDGE)->y; \
+        dy = (pEDGE)->celldy; \
+        ylast = (pEDGE)->ybot; \
+        if (ylast <= (CY1) || y >= (CY2) || dy == 0.0) { \
+            break; \
+        } \
+        x = (pEDGE)->x; \
+        dx = (pEDGE)->celldx; \
+        if (ylast > (CY2)) { \
+            ylast = (CY2); \
+            xlast = (pEDGE)->xnexty; \
+        } else { \
+            xlast = (pEDGE)->xbot; \
+        } \
+        xnext = (pEDGE)->xnextx; \
+        ynext = (pEDGE)->ynextx; \
+        mult = ((pEDGE)->isTrailing) ? -1.0 : 1.0; \
+        while (ynext <= ylast) { \
+            INSERT_ACCUM(pACCUM, IMIN, IMAX, \
+                         x, y, xnext, ynext, \
+                         CX1, CX2, mult); \
+            x = xnext; \
+            y = ynext; \
+            xnext += dx; \
+            ynext += dy; \
+        } \
+        (pEDGE)->ynextx = ynext; \
+        (pEDGE)->xnextx = xnext; \
+        INSERT_ACCUM(pACCUM, IMIN, IMAX, \
+                     x, y, xlast, ylast, \
+                     CX1, CX2, mult); \
+        (pEDGE)->x = xlast; \
+        (pEDGE)->y = ylast; \
+        (pEDGE)->xnexty = xlast + (pEDGE)->linedx; \
+    } while(0)
+
+/* Main function to fill a single Parallelogram */
+static void
+fillAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+            CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+            void *pDst,
+            jdouble x1, jdouble y1,
+            jdouble dx1, jdouble dy1,
+            jdouble dx2, jdouble dy2)
+{
+    jint cx1 = pRasInfo->bounds.x1;
+    jint cy1 = pRasInfo->bounds.y1;
+    jint cx2 = pRasInfo->bounds.x2;
+    jint cy2 = pRasInfo->bounds.y2;
+    jint width = cx2 - cx1;
+    EdgeInfo edges[4];
+    jfloat localaccum[MASK_BUF_LEN + 1];
+    jfloat *pAccum;
+
+    if (!storePgram(edges + 0, edges + 2,
+                    x1, y1, dx1, dy1, dx2, dy2,
+                    cx1, cy1, cx2, cy2,
+                    JNI_FALSE))
+    {
+        return;
+    }
+
+    pAccum = ((width > MASK_BUF_LEN)
+              ? malloc((width + 1) * sizeof(jfloat))
+              : localaccum);
+    if (pAccum == NULL) {
+        return;
+    }
+    memset(pAccum, 0, (width+1) * sizeof(jfloat));
+
+    while (cy1 < cy2) {
+        jint lmin, lmax, rmin, rmax;
+        jint moff, x;
+        jdouble accum;
+        unsigned char lastcov;
+
+        lmin = rmin = width + 2;
+        lmax = rmax = 0;
+        ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[2], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[3], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        if (lmax > width) {
+            lmax = width; /* Extra col has data we do not need. */
+        }
+        if (rmax > width) {
+            rmax = width; /* Extra col has data we do not need. */
+        }
+        /* If ranges overlap, handle both in the first pass. */
+        if (rmin <= lmax) {
+            lmax = rmax;
+        }
+
+        x = lmin;
+        accum = 0.0;
+        moff = 0;
+        lastcov = 0;
+        while (x < lmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = lastcov = DblToMask(accum);
+            x++;
+        }
+        /* Check for a solid center section. */
+        if (lastcov == 0xFF) {
+            jint endx;
+            void *pRow;
+
+            /* First process the existing partial coverage data. */
+            if (moff > 0) {
+                pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+                (*pPrim->funcs.maskfill)(pRow,
+                                         pMask, 0, 0,
+                                         moff, 1,
+                                         color, pRasInfo,
+                                         pPrim, pCompInfo);
+                moff = 0;
+            }
+
+            /* Where does the center section end? */
+            /* If there is no right AA edge in the accum buffer, then */
+            /* the right edge was beyond the clip, so fill out to width */
+            endx = (rmin < rmax) ? rmin : width;
+            if (x < endx) {
+                pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+                (*pPrim->funcs.maskfill)(pRow,
+                                         NULL, 0, 0,
+                                         endx - x, 1,
+                                         color, pRasInfo,
+                                         pPrim, pCompInfo);
+                x = endx;
+            }
+        } else if (lastcov > 0 && rmin >= rmax) {
+            /* We are not at 0 coverage, but there is no right edge, */
+            /* force a right edge so we process pixels out to width. */
+            rmax = width;
+        }
+        /* The following loop will process the right AA edge and/or any */
+        /* partial coverage center section not processed above. */
+        while (x < rmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = DblToMask(accum);
+            x++;
+        }
+        if (moff > 0) {
+            void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+            (*pPrim->funcs.maskfill)(pRow,
+                                     pMask, 0, 0,
+                                     moff, 1,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
+        cy1++;
+    }
+    if (pAccum != localaccum) {
+        free(pAccum);
+    }
+}
+
+/*
+ * Class:     sun_java2d_loops_MaskFill
+ * Method:    FillAAPgram
+ * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDD)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_loops_MaskFill_FillAAPgram
+    (JNIEnv *env, jobject self,
+     jobject sg2d, jobject sData, jobject comp,
+     jdouble x0, jdouble y0,
+     jdouble dx1, jdouble dy1,
+     jdouble dx2, jdouble dy2)
+{
+    SurfaceDataOps *sdOps;
+    SurfaceDataRasInfo rasInfo;
+    NativePrimitive *pPrim;
+    CompositeInfo compInfo;
+    jint ix1, iy1, ix2, iy2;
+
+    if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
+        return;
+    }
+
+    /*
+     * Sort parallelogram by y values, ensure that each delta vector
+     * has a non-negative y delta.
+     */
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
+
+    PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_TRUE);
+    iy1 = (jint) floor(y0);
+    iy2 = (jint) ceil(y0 + dy1 + dy2);
+
+    pPrim = GetNativePrim(env, self);
+    if (pPrim == NULL) {
+        return;
+    }
+    if (pPrim->pCompType->getCompInfo != NULL) {
+        (*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
+    }
+
+    sdOps = SurfaceData_GetOps(env, sData);
+    if (sdOps == 0) {
+        return;
+    }
+
+    GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
+    SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
+    if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
+        rasInfo.bounds.x2 <= rasInfo.bounds.x1)
+    {
+        return;
+    }
+
+    if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
+        return;
+    }
+
+    ix1 = rasInfo.bounds.x1;
+    iy1 = rasInfo.bounds.y1;
+    ix2 = rasInfo.bounds.x2;
+    iy2 = rasInfo.bounds.y2;
+    if (ix2 > ix1 && iy2 > iy1) {
+        jint width = ix2 - ix1;
+        jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
+        unsigned char localmask[MASK_BUF_LEN];
+        unsigned char *pMask = ((width > MASK_BUF_LEN)
+                                ? malloc(width)
+                                : localmask);
+
+        sdOps->GetRasInfo(env, sdOps, &rasInfo);
+        if (rasInfo.rasBase != NULL && pMask != NULL) {
+            void *pDst = PtrCoord(rasInfo.rasBase,
+                                  ix1, rasInfo.pixelStride,
+                                  iy1, rasInfo.scanStride);
+            if (dy1 == 0 && dx2 == 0) {
+                if (dx1 < 0) {
+                    // We sorted by Y above, but not by X
+                    x0 += dx1;
+                    dx1 = -dx1;
+                }
+                fillAARect(pPrim, &rasInfo, &compInfo,
+                           color, pMask, pDst,
+                           x0, y0, x0+dx1, y0+dy2);
+            } else if (dx1 == 0 && dy2 == 0) {
+                if (dx2 < 0) {
+                    // We sorted by Y above, but not by X
+                    x0 += dx2;
+                    dx2 = -dx2;
+                }
+                fillAARect(pPrim, &rasInfo, &compInfo,
+                           color, pMask, pDst,
+                           x0, y0, x0+dx2, y0+dy1);
+            } else {
+                fillAAPgram(pPrim, &rasInfo, &compInfo,
+                            color, pMask, pDst,
+                            x0, y0, dx1, dy1, dx2, dy2);
+            }
+        }
+        SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+        if (pMask != NULL && pMask != localmask) {
+            free(pMask);
+        }
     }
     SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
 }
+
+/* Main function to fill a double pair of (inner and outer) parallelograms */
+static void
+drawAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
+            CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
+            void *pDst,
+            jdouble ox0, jdouble oy0,
+            jdouble dx1, jdouble dy1,
+            jdouble dx2, jdouble dy2,
+            jdouble ldx1, jdouble ldy1,
+            jdouble ldx2, jdouble ldy2)
+{
+    jint cx1 = pRasInfo->bounds.x1;
+    jint cy1 = pRasInfo->bounds.y1;
+    jint cx2 = pRasInfo->bounds.x2;
+    jint cy2 = pRasInfo->bounds.y2;
+    jint width = cx2 - cx1;
+    EdgeInfo edges[8];
+    jfloat localaccum[MASK_BUF_LEN + 1];
+    jfloat *pAccum;
+
+    if (!storePgram(edges + 0, edges + 6,
+                    ox0, oy0,
+                    dx1 + ldx1, dy1 + ldy1,
+                    dx2 + ldx2, dy2 + ldy2,
+                    cx1, cy1, cx2, cy2,
+                    JNI_FALSE))
+    {
+        /* If outer pgram does not contribute, then inner cannot either. */
+        return;
+    }
+    storePgram(edges + 2, edges + 4,
+               ox0 + ldx1 + ldx2, oy0 + ldy1 + ldy2,
+               dx1 - ldx1, dy1 - ldy1,
+               dx2 - ldx2, dy2 - ldy2,
+               cx1, cy1, cx2, cy2,
+               JNI_TRUE);
+
+    pAccum = ((width > MASK_BUF_LEN)
+              ? malloc((width + 1) * sizeof(jfloat))
+              : localaccum);
+    if (pAccum == NULL) {
+        return;
+    }
+    memset(pAccum, 0, (width+1) * sizeof(jfloat));
+
+    while (cy1 < cy2) {
+        jint lmin, lmax, rmin, rmax;
+        jint moff, x;
+        jdouble accum;
+        unsigned char lastcov;
+
+        lmin = rmin = width + 2;
+        lmax = rmax = 0;
+        ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[2], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[3], pAccum, lmin, lmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[4], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[5], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[6], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        ACCUM_EDGE(&edges[7], pAccum, rmin, rmax,
+                   cx1, cy1, cx2, cy1+1);
+        if (lmax > width) {
+            lmax = width; /* Extra col has data we do not need. */
+        }
+        if (rmax > width) {
+            rmax = width; /* Extra col has data we do not need. */
+        }
+        /* If ranges overlap, handle both in the first pass. */
+        if (rmin <= lmax) {
+            lmax = rmax;
+        }
+
+        x = lmin;
+        accum = 0.0;
+        moff = 0;
+        lastcov = 0;
+        while (x < lmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = lastcov = DblToMask(accum);
+            x++;
+        }
+        /* Check for an empty or solidcenter section. */
+        if (lastcov == 0 || lastcov == 0xFF) {
+            jint endx;
+            void *pRow;
+
+            /* First process the existing partial coverage data. */
+            if (moff > 0) {
+                pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+                (*pPrim->funcs.maskfill)(pRow,
+                                         pMask, 0, 0,
+                                         moff, 1,
+                                         color, pRasInfo,
+                                         pPrim, pCompInfo);
+                moff = 0;
+            }
+
+            /* Where does the center section end? */
+            /* If there is no right AA edge in the accum buffer, then */
+            /* the right edge was beyond the clip, so fill out to width */
+            endx = (rmin < rmax) ? rmin : width;
+            if (x < endx) {
+                if (lastcov == 0xFF) {
+                    pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+                    (*pPrim->funcs.maskfill)(pRow,
+                                             NULL, 0, 0,
+                                             endx - x, 1,
+                                             color, pRasInfo,
+                                             pPrim, pCompInfo);
+                }
+                x = endx;
+            }
+        } else if (rmin >= rmax) {
+            /* We are not at 0 coverage, but there is no right edge, */
+            /* force a right edge so we process pixels out to width. */
+            rmax = width;
+        }
+        /* The following loop will process the right AA edge and/or any */
+        /* partial coverage center section not processed above. */
+        while (x < rmax) {
+            accum += pAccum[x];
+            pAccum[x] = 0.0f;
+            pMask[moff++] = lastcov = DblToMask(accum);
+            x++;
+        }
+        if (moff > 0) {
+            void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
+            (*pPrim->funcs.maskfill)(pRow,
+                                     pMask, 0, 0,
+                                     moff, 1,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        if (lastcov == 0xFF && x < width) {
+            void *pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
+            (*pPrim->funcs.maskfill)(pRow,
+                                     NULL, 0, 0,
+                                     width - x, 1,
+                                     color, pRasInfo,
+                                     pPrim, pCompInfo);
+        }
+        pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
+        cy1++;
+    }
+    if (pAccum != localaccum) {
+        free(pAccum);
+    }
+}
+
+/*
+ * Class:     sun_java2d_loops_MaskFill
+ * Method:    DrawAAPgram
+ * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDDDD)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_loops_MaskFill_DrawAAPgram
+    (JNIEnv *env, jobject self,
+     jobject sg2d, jobject sData, jobject comp,
+     jdouble x0, jdouble y0,
+     jdouble dx1, jdouble dy1,
+     jdouble dx2, jdouble dy2,
+     jdouble lw1, jdouble lw2)
+{
+    SurfaceDataOps *sdOps;
+    SurfaceDataRasInfo rasInfo;
+    NativePrimitive *pPrim;
+    CompositeInfo compInfo;
+    jint ix1, iy1, ix2, iy2;
+    jdouble ldx1, ldy1, ldx2, ldy2;
+    jdouble ox0, oy0;
+
+    if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
+        return;
+    }
+
+    /*
+     * Sort parallelogram by y values, ensure that each delta vector
+     * has a non-negative y delta.
+     */
+    SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
+               v = lw1; lw1 = lw2; lw2 = v;);
+
+    // dx,dy for line width in the "1" and "2" directions.
+    ldx1 = dx1 * lw1;
+    ldy1 = dy1 * lw1;
+    ldx2 = dx2 * lw2;
+    ldy2 = dy2 * lw2;
+
+    // calculate origin of the outer parallelogram
+    ox0 = x0 - (ldx1 + ldx2) / 2.0;
+    oy0 = y0 - (ldy1 + ldy2) / 2.0;
+
+    if (lw1 >= 1.0 || lw2 >= 1.0) {
+        /* Only need to fill an outer pgram if the interior no longer
+         * has a hole in it (i.e. if either of the line width ratios
+         * were greater than or equal to 1.0).
+         */
+        Java_sun_java2d_loops_MaskFill_FillAAPgram(env, self,
+                                                   sg2d, sData, comp,
+                                                   ox0, oy0,
+                                                   dx1 + ldx1, dy1 + ldy1,
+                                                   dx2 + ldx2, dy2 + ldy2);
+        return;
+    }
+
+    PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_TRUE);
+    iy1 = (jint) floor(oy0);
+    iy2 = (jint) ceil(oy0 + dy1 + ldy1 + dy2 + ldy2);
+
+    pPrim = GetNativePrim(env, self);
+    if (pPrim == NULL) {
+        return;
+    }
+    if (pPrim->pCompType->getCompInfo != NULL) {
+        (*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
+    }
+
+    sdOps = SurfaceData_GetOps(env, sData);
+    if (sdOps == 0) {
+        return;
+    }
+
+    GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
+    SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
+    if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
+        rasInfo.bounds.x2 <= rasInfo.bounds.x1)
+    {
+        return;
+    }
+
+    if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
+        return;
+    }
+
+    ix1 = rasInfo.bounds.x1;
+    iy1 = rasInfo.bounds.y1;
+    ix2 = rasInfo.bounds.x2;
+    iy2 = rasInfo.bounds.y2;
+    if (ix2 > ix1 && iy2 > iy1) {
+        jint width = ix2 - ix1;
+        jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
+        unsigned char localmask[MASK_BUF_LEN];
+        unsigned char *pMask = ((width > MASK_BUF_LEN)
+                                ? malloc(width)
+                                : localmask);
+
+        sdOps->GetRasInfo(env, sdOps, &rasInfo);
+        if (rasInfo.rasBase != NULL && pMask != NULL) {
+            void *pDst = PtrCoord(rasInfo.rasBase,
+                                  ix1, rasInfo.pixelStride,
+                                  iy1, rasInfo.scanStride);
+            /*
+             * NOTE: aligned rects could probably be drawn
+             * even faster with a little work here.
+             * if (dy1 == 0 && dx2 == 0) {
+             *     drawAARect(pPrim, &rasInfo, &compInfo,
+             *                color, pMask, pDst,
+             *                ox0, oy0, ox0+dx1+ldx1, oy0+dy2+ldy2, ldx1, ldy2);
+             * } else if (dx1 == 0 && dy2 == 0) {
+             *     drawAARect(pPrim, &rasInfo, &compInfo,
+             *                color, pMask, pDst,
+             *                ox0, oy0, ox0+dx2+ldx2, oy0+dy1+ldy1, ldx2, ldy1);
+             * } else {
+             */
+            drawAAPgram(pPrim, &rasInfo, &compInfo,
+                        color, pMask, pDst,
+                        ox0, oy0,
+                        dx1, dy1, dx2, dy2,
+                        ldx1, ldy1, ldx2, ldy2);
+            /*
+             * }
+             */
+        }
+        SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
+        if (pMask != NULL && pMask != localmask) {
+            free(pMask);
+        }
+    }
+    SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/java2d/loops/ParallelogramUtils.h	Wed Jan 19 19:00:30 2011 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef ParallelogramUtils_h_Included
+#define ParallelogramUtils_h_Included
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2, AA) \
+    do { \
+        double vmin, vmax; \
+        if (dv1 < 0) { \
+            vmin = v0+dv1; \
+            vmax = v0; \
+        } else { \
+            vmin = v0; \
+            vmax = v0+dv1; \
+        } \
+        if (dv2 < 0) { \
+            vmin += dv2; \
+        } else { \
+            vmax += dv2; \
+        } \
+        if (AA) { \
+            bmin = (jint) floor(vmin); \
+            bmax = (jint) ceil(vmax); \
+        } else { \
+            bmin = (jint) floor(vmin + 0.5); \
+            bmax = (jint) floor(vmax + 0.5); \
+        } \
+    } while(0)
+
+#define PGRAM_INIT_X(starty, x, y, slope) \
+    (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
+
+/*
+ * Sort parallelogram by y values, ensure that each delta vector
+ * has a non-negative y delta.
+ */
+#define SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, OTHER_SWAP_CODE) \
+    do { \
+        if (dy1 < 0) { \
+            x0 += dx1;  y0 += dy1; \
+            dx1 = -dx1; dy1 = -dy1; \
+        } \
+        if (dy2 < 0) { \
+            x0 += dx2;  y0 += dy2; \
+            dx2 = -dx2; dy2 = -dy2; \
+        } \
+        /* Sort delta vectors so dxy1 is left of dxy2. */ \
+        if (dx1 * dy2 > dx2 * dy1) { \
+            double v; \
+            v = dx1; dx1 = dx2; dx2 = v; \
+            v = dy1; dy1 = dy2; dy2 = v; \
+            OTHER_SWAP_CODE \
+        } \
+    } while(0)
+
+#endif /* ParallelogramUtils_h_Included */
--- a/jdk/src/share/native/sun/java2d/pipe/BufferedMaskBlit.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/share/native/sun/java2d/pipe/BufferedMaskBlit.c	Wed Jan 19 19:00:30 2011 -0800
@@ -119,7 +119,8 @@
                 PtrCoord(srcInfo.rasBase,
                          srcInfo.bounds.x1, srcInfo.pixelStride,
                          srcInfo.bounds.y1, srcInfo.scanStride);
-            unsigned char *pMask =
+            unsigned char *pMask, *pMaskAlloc;
+            pMask = pMaskAlloc =
                 (*env)->GetPrimitiveArrayCritical(env, maskArray, 0);
             if (pMask == NULL) {
                 J2dRlsTraceLn(J2D_TRACE_ERROR,
@@ -274,7 +275,7 @@
             bpos += width * height * sizeof(jint);
 
             (*env)->ReleasePrimitiveArrayCritical(env, maskArray,
-                                                  pMask, JNI_ABORT);
+                                                  pMaskAlloc, JNI_ABORT);
         }
         SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
     }
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Wed Jan 19 19:00:30 2011 -0800
@@ -137,41 +137,43 @@
         file = fopen(ALSA_VERSION_PROC_FILE, "r");
         ALSAVersionString[0] = 0;
         if (file) {
-            fgets(ALSAVersionString, ALSAVersionString_LENGTH, file);
-            // parse for version number
-            totalLen = strlen(ALSAVersionString);
-            inVersionString = FALSE;
-            len = 0;
-            curr = 0;
-            while (curr < totalLen) {
-                if (!inVersionString) {
-                    // is this char the beginning of a version string ?
-                    if (ALSAVersionString[curr] >= '0'
-                        && ALSAVersionString[curr] <= '9') {
-                        inVersionString = TRUE;
+            if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
+                // parse for version number
+                totalLen = strlen(ALSAVersionString);
+                inVersionString = FALSE;
+                len = 0;
+                curr = 0;
+                while (curr < totalLen) {
+                    if (!inVersionString) {
+                        // is this char the beginning of a version string ?
+                        if (ALSAVersionString[curr] >= '0'
+                            && ALSAVersionString[curr] <= '9') {
+                            inVersionString = TRUE;
+                        }
                     }
+                    if (inVersionString) {
+                        // the version string ends with white space
+                        if (ALSAVersionString[curr] <= 32) {
+                            break;
+                        }
+                        if (curr != len) {
+                            // copy this char to the beginning of the string
+                            ALSAVersionString[len] = ALSAVersionString[curr];
+                        }
+                        len++;
+                    }
+                    curr++;
                 }
-                if (inVersionString) {
-                    // the version string ends with white space
-                    if (ALSAVersionString[curr] <= 32) {
-                        break;
-                    }
-                    if (curr != len) {
-                        // copy this char to the beginning of the string
-                        ALSAVersionString[len] = ALSAVersionString[curr];
-                    }
-                    len++;
+                // remove trailing dots
+                while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
+                    len--;
                 }
-                curr++;
+                // null terminate
+                ALSAVersionString[len] = 0;
             }
-            // remove trailing dots
-            while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
-                len--;
-            }
-            // null terminate
-            ALSAVersionString[len] = 0;
+            fclose(file);
+            hasGottenALSAVersion = TRUE;
         }
-        hasGottenALSAVersion = TRUE;
     }
     strncpy(buffer, ALSAVersionString, len);
 }
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiIn.c	Wed Jan 19 19:00:30 2011 -0800
@@ -32,6 +32,9 @@
 #include <alsa/asoundlib.h>
 #include "PlatformMidi.h"
 #include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
+#if defined(i586)
+#include <sys/utsname.h>
+#endif
 
 /*
  * Helper methods
@@ -73,9 +76,38 @@
     return (char*) getErrorStr(err);
 }
 
+INT32 MIDI_IN_GetNumDevices() {
+/* Workaround for 6842956: 32bit app on 64bit linux
+ * gets assertion failure trying to open midiIn ports.
+ * Untill the issue is fixed in ALSA
+ * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
+ * report no midi in devices in the configuration.
+ */
+#if defined(i586)
+    static int jre32onlinux64 = -1;
+    if (jre32onlinux64 < 0) {
+        jre32onlinux64 = 0;
+        /* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
+         * environment variable.
+         */
+        if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
+            struct utsname u;
+            jre32onlinux64 = 0;
+            if (uname(&u) == 0) {
+                if (strstr(u.machine, "64") != NULL) {
+                    TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
+                    jre32onlinux64 = 1;
+                }
+            }
+        }
+    }
+    if (jre32onlinux64) {
+        return 0;
+    }
+#endif
 
-INT32 MIDI_IN_GetNumDevices() {
     TRACE0("MIDI_IN_GetNumDevices()\n");
+
     return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
 }
 
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_MidiUtils.c	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -372,7 +372,7 @@
     snd_rawmidi_t* native_handle;
     snd_midi_event_t* event_parser = NULL;
     int err;
-    UINT32 deviceID;
+    UINT32 deviceID = 0;
     char devicename[100];
 #ifdef ALSA_MIDI_USE_PLUGHW
     int usePlugHw = 1;
--- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Mon Jan 17 13:29:12 2011 +0530
+++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c	Wed Jan 19 19:00:30 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,7 @@
     int ret;
     int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
     int origSampleSizeInBytes, origSignificantBits;
-    int channels, minChannels, maxChannels;
+    unsigned int channels, minChannels, maxChannels;
     int rate, bitIndex;
 
     for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
@@ -152,7 +152,6 @@
             }
         }
         snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
-#ifdef ALSA_PCM_NEW_HW_PARAMS_API
         if (ret == 0) {
             ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
             if (ret != 0) {
@@ -165,13 +164,6 @@
                 ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
             }
         }
-#else
-        minChannels = snd_pcm_hw_params_get_channels_min(hwParams);
-        maxChannels = snd_pcm_hw_params_get_channels_max(hwParams);
-        if (minChannels > maxChannels) {
-            ERROR2("MinChannels=%d, maxChannels=%d\n", minChannels, maxChannels);
-        }
-#endif
 
         // since we queried the hw: device, for many soundcards, it will only
         // report the maximum number of channels (which is the only way to talk
@@ -222,7 +214,7 @@
                                 } else {
                                     for (channels = minChannels; channels <= maxChannels; channels++) {